3 回答
TA贡献1951条经验 获得超3个赞
下面是一个异步版本,它首先将表单数据转换为 Blob。从中可以检索要发送到服务器的实际大小。
因此,您不会发布表单数据,而是发送生成的 blob。
async function test() {
// Create some dummy data
const fd = new FormData()
fd.set('a', 'b')
// acquire an actual raw bytes as blob of what the request would send
const res = new Response(fd)
const blob = await res.blob()
blob.text && (
console.log('what the actual body looks like'),
console.log(await blob.text())
)
// can't use own blob's type since spec lowercase the blob.type
// so we get the actual content type
const type = res.headers.get('content-type')
// the acutal content-length size that's going to be used
console.log('content-length before sending', blob.size)
// verify
const testRes = await fetch('https://httpbin.org/post', {
method: 'POST',
body: blob, // now send the blob instead of formdata
headers: { // use the real type (and not the default lowercased blob type)
'content-type': type
}
})
const json = await testRes.json()
const headers = new Headers(json.headers)
console.log('form that got posted:', JSON.stringify(json.form))
console.log('content-length that was sent', headers.get('content-length'))
}
但是,这在IE和野生动物园中不起作用
IE没有抓取(但无论如何它已经死了)
野生动物园有这个错误。
all doe,将表单数据替换为多填充版本(如 https://github.com/jimmywarting/FormData)可能有助于您将表单数据直接(同步)转换为 blob,而无需使用提取 API(使用 )。也就是说,如果您需要更广泛的浏览器支持formData._blob()
TA贡献1818条经验 获得超3个赞
我仍然不知道是否有可能计算出确切的大小,但您至少可以尝试估计它:
/**
* Estimate the content length of (multipart/form-data) encoded form data
* object (sent in HTTP POST requests).
* We do not know if you can get the actual content length.
* Hence, it is estimated by this function.
* As soon as {@link https://stackoverflow.com/q/62281752/1065654 this}
* question is answered (correctly), the correct calculation should be used.
*
* @param formData
*/
function estimateContentLength(formData: FormData) {
// Seems to be 44 in WebKit browsers (e.g. Chrome, Safari, etc.),
// but varies at least in Firefox.
const baseLength = 50; // estimated max value
// Seems to be 87 in WebKit browsers (e.g. Chrome, Safari, etc.),
// but varies at least in Firefox.
const separatorLength = 115; // estimated max value
let length = baseLength;
const entries = formData.entries();
for (const [key, value] of entries) {
length += key.length + separatorLength;
if (typeof value === 'object') {
length += value.size;
} else {
length += String(value).length;
}
}
return length;
}
TA贡献1862条经验 获得超6个赞
一种方法可能是 FormData.entries(),因此您可以循环访问所有数据并获取最终的内容长度。我们还需要一个 over 数组,或者您可以使用 将 返回的迭代器转换为正确的数组。spread operatorArray.from().entries()
下面的代码示例,我没有用文件测试它,但让我知道你是否有任何边缘情况与这个。
function getContentLength(formData) {
const formDataEntries = [...formData.entries()]
const contentLength = formDataEntries.reduce((acc, [key, value]) => {
if (typeof value === 'string') return acc + value.length
if (typeof value === 'object') return acc + value.size
return acc
}, 0)
return contentLength
}
添加回答
举报