javascript - 如何在 JavaScript 中验证多部分表单数据的内容长度?

标签 javascript multipartform-data form-data content-length http-content-length

我将 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

chrome

在我的 Firefox 浏览器中为 172。我不确定其他浏览器的行为方式。

Firefox

最佳答案

我仍然不知道是否可以计算出确切的大小,但你至少可以尝试估计一下:

/**
 * 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;
}

关于javascript - 如何在 JavaScript 中验证多部分表单数据的内容长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62281752/

相关文章:

用于绑定(bind)对象中指定事件的 JavaScript 函数

javascript - 输入数据后退出模态

javascript - 动态生成的 html/ionic 复选框内的 ng-change 未绑定(bind)

javascript - 管道多部分表单上传到另一台服务器

javascript - Angular 2 排序列表动画

http - 是否有 HTTP 验证器来显示我的供应商的 API 是否创建了格式错误的 POST?

iphone - 使用 AFNetworking 发送多张图像

javascript - 在 FormData 中发送整数

jquery - 使用 jQuery.ajax 发送 multipart/formdata

reactjs - React - 带有文件和字符串的 Axios POST 表单数据