我发帖 FormData
(包括文件)到服务器,拒绝内容长度超过特定限制的请求。我想在做一个注定要被拒绝的请求之前,在我的JavaScript客户端(浏览器)中验证内容长度。我如何获得我的(multipart/form-data
)编码的 FormData
对象?
const formData = new FormData();
formData.append('text', text);
formData.append('file', file);
if (getContentLength(formData) > limit) {
alert('Content length limit is exceeded');
} else {
fetch(url, { method: 'POST', body: formData });
}
编辑。 谢谢你的回答, @Indgalante. 只是使用 length
弦之 size
的文件没有计算出正确的内容长度。
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
}
const formData = new FormData();
formData.append('text', 'foo');
alert(`calculated content-length is ${getContentLength(formData)}`);
fetch('https://httpbin.org/post', { method: 'POST', body: formData });
你没有考虑到表格数据是在请求中编码的。因此,i.a.边界被添加了。示例中计算出的内容长度是3,但在我的Chrome浏览器中应该是138。
和172在我的Firefox浏览器。我不知道其他浏览器的表现如何。
一种方法可以是 FormData. entries() 这样你就可以对所有的数据进行迭代,并得到最终的内容长度.我们还需要一个 spread operator
在一个数组上,或者你可以使用 Array.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
}