如何提取通过 multipart/form-data 发送的文件的内容类型
How to extract the Content-Type of a file sent via multipart/form-data
我在我的 cloudflare worker 中收到一个请求,想要将数据上传到 Google 云存储。我的问题是我无法从收到的 multipart/form-data 数据中提取内容类型,以便将其以正确的内容类型上传到 GCS。
当我使用 await req.formData()
读取请求时,我可以 get('file')
来自 formData 并且它 returns 我需要 GCS 的原始文件数据,但我似乎不能在任何地方查看我需要的文件内容类型(我只能在查看原始请求正文时看到它)。
这是我的(简化的)代码:
event.respondWith((async () => {
const req = event.request
const formData = await req.formData()
const file = formData.get('file')
const filename = formData.get('filename')
const oauth = await getGoogleOAuth()
const gcsOptions = {
method: 'PUT',
headers: {
Authorization: oauth.token_type + ' ' + oauth.access_token,
'Content-Type': 'application/octet-stream' //this should by `'Content-Type': file.type`
},
body: file,
}
const gcsRes = await fetch(
`https://storage.googleapis.com/***-media/${filename}`,
gcsOptions,
)
if (gcsRes.status === 200) {
return new Response(JSON.stringify({filename}), gcsRes)
} else {
return new Response('Internal Server Error', {status: 500, statusText: 'Internal Server Error'})
}
})())
提醒 - 该代码是我们的 cloudflare worker 代码的一部分。
在我看来这应该是直截了当的,确定您从 multipart/form-data 数据中提取的文件类型。
我错过了什么吗?
不幸的是,在撰写本文时,Cloudflare Workers 的 FormData 实现不完整,并且不允许提取 Content-Type。事实上,我们的实现目前似乎将所有条目解释为文本和 return 字符串,这意味着二进制内容将被破坏。这是一个需要小心修复的错误,因为我们不想破坏可能依赖错误行为的已部署脚本。
感谢 Kenton 的回复。
我最后做了什么:
由于 Cloudflare Workers 不支持 Blob 的 multipart/form-data
或字符串以外的任何类型,我最终使用了 ArrayBuffer
数据类型中的原始字节。将其转换为 Uint8Array
后,我逐字节解析它以确定文件类型以及文件数据的开始和结束索引。找到传输文件的开头和结尾后,我就可以创建一个文件数据数组,将其添加到请求中并将其发送到 GCS,如上所示。
我在我的 cloudflare worker 中收到一个请求,想要将数据上传到 Google 云存储。我的问题是我无法从收到的 multipart/form-data 数据中提取内容类型,以便将其以正确的内容类型上传到 GCS。
当我使用 await req.formData()
读取请求时,我可以 get('file')
来自 formData 并且它 returns 我需要 GCS 的原始文件数据,但我似乎不能在任何地方查看我需要的文件内容类型(我只能在查看原始请求正文时看到它)。
这是我的(简化的)代码:
event.respondWith((async () => {
const req = event.request
const formData = await req.formData()
const file = formData.get('file')
const filename = formData.get('filename')
const oauth = await getGoogleOAuth()
const gcsOptions = {
method: 'PUT',
headers: {
Authorization: oauth.token_type + ' ' + oauth.access_token,
'Content-Type': 'application/octet-stream' //this should by `'Content-Type': file.type`
},
body: file,
}
const gcsRes = await fetch(
`https://storage.googleapis.com/***-media/${filename}`,
gcsOptions,
)
if (gcsRes.status === 200) {
return new Response(JSON.stringify({filename}), gcsRes)
} else {
return new Response('Internal Server Error', {status: 500, statusText: 'Internal Server Error'})
}
})())
提醒 - 该代码是我们的 cloudflare worker 代码的一部分。
在我看来这应该是直截了当的,确定您从 multipart/form-data 数据中提取的文件类型。 我错过了什么吗?
不幸的是,在撰写本文时,Cloudflare Workers 的 FormData 实现不完整,并且不允许提取 Content-Type。事实上,我们的实现目前似乎将所有条目解释为文本和 return 字符串,这意味着二进制内容将被破坏。这是一个需要小心修复的错误,因为我们不想破坏可能依赖错误行为的已部署脚本。
感谢 Kenton 的回复。
我最后做了什么:
由于 Cloudflare Workers 不支持 Blob 的 multipart/form-data
或字符串以外的任何类型,我最终使用了 ArrayBuffer
数据类型中的原始字节。将其转换为 Uint8Array
后,我逐字节解析它以确定文件类型以及文件数据的开始和结束索引。找到传输文件的开头和结尾后,我就可以创建一个文件数据数组,将其添加到请求中并将其发送到 GCS,如上所示。