如何解决我应该如何解码文件的内容以将其包含在多部分/表单数据POST请求中?
我处于一种必须手动构造多部分/表单数据POST请求主体的情况。我了解该结构很好,并且可以成功上传不包含文件的表单。我有一个文件作为File
对象,我需要将文件的内容解释为字符串,以将其包含在请求的正文中。我所遇到的所有包含文件的多部分表单数据的示例都具有“文件内容移至此处” 之类的内容,其中包含了文件,并且从不讨论如何从文件获取到字符串。 this问题的最高答案接近于我要寻找的答案,但是我宁愿避免base64的额外开销,因为我的表单将处理许多文件。我发现了
`
--${boundary}
Content-Disposition: form-data; name="file"; filename="${file.name}"
Content-Type: ${file.type}
${await file.text()}`
仅适用于简单的pdf,但不能使用jpeg(这里的“失败”表示我的服务器无法正确解析图像)。
我有一个使用FormData
实例和Fetch的示例(我不能在生产中使用FormData
)。在Chrome开发人员工具中,我可以获取请求的原始内容,以查看文件的外观。这是文件开头的样子:
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
ÿØÿî!AdobedÀ E¿d„¾¤ÿÛ„
$$''$$53335;;;;;;;;;;
使用file.text()
消息的相同部分看起来像:
����!Adobed� E�d������
$$''$$5333
当文件被这样解码时:
`
--${boundary}
Content-Disposition: form-data; name="file"; filename="${file.name}"
Content-Type: ${file.type}
${String.fromCharCode.apply(null,new Uint8Array(await file.arrayBuffer()))}`
}
result += `
文件的开头看起来正确,但是比较完整的字符串表明存在一些差异。
我发现了
4.3 Encoding
While the HTTP protocol can transport arbitrary binary data,the
default for mail transport is the 7BIT encoding. The value supplied
for a part may need to be encoded and the "content-transfer-encoding"
header supplied if the value does not conform to the default
encoding. [See section 5 of RFC 2046 for more details.]
在RFC 2388中,但我认为这是指请求主体是通过有线方式发送的,而不是主体的构造方式。我觉得我在这里缺少一些核心概念。任何帮助将不胜感激。
编辑: 这是将表单数据发送到我的服务器的方式:
const response = await fetch(url,{
method: 'POST',// *GET,POST,PUT,DELETE,etc.
mode: 'cors',// no-cors,*cors,same-origin
cache: 'no-cache',// *default,no-cache,reload,force-cache,only-if-cached
credentials: 'same-origin',// include,*same-origin,omit
redirect: 'follow',// manual,*follow,error
referrer: 'no-referrer',// no-referrer,*client
body: serializedData,// body data type must match "Content-Type" header
headers: {
'Content-Type': 'multipart/form-data; boundary=' + boundary,},})
解决方法
4.10.21.7多部分表单数据多部分/表单数据编码算法(给出条目列表和编码)如下:
让结果为空字符串。
对于条目列表中的每个条目:
对于条目名称和值中不能包含的每个字符 使用所选字符编码表示,替换字符 由包含U + 0026 AMPERSAND字符(&),U + 0023的字符串组成 NUMBER SIGN字符(#),一个或多个ASCII数字代表 字符的十进制代码点,最后是U + 003B(;)。
使用RFC描述的规则对(现在已突变的)条目列表进行编码 7578,从表单返回值:multipart / form-data,并返回 结果字节流。 [RFC7578]
条目列表中的每个条目都是一个字段,条目的名称是 字段名称,而条目的值就是该字段的值。
零件的顺序必须与输入字段的顺序相同 清单。具有相同名称的多个条目必须被视为不同的 字段。
已生成的multipart / form-data资源的组成部分 对应于非文件字段,必须没有
Content-Type
标头 指定。它们的名称和值必须使用字符编码 上面选择的编码。生成的multipart / form-data资源中包含的文件名(以 文件字段的一部分)必须使用上面选择的字符编码, 尽管如有必要,可以使用确切的名称(例如 可以从文件名中删除换行符,将引号更改为 “%22”,并且所选字符中无法表达的字符 编码可以替换为其他字符。
用户代理在生成的返回值时使用的边界 该算法是多部分/表单数据边界字符串。 (此值 用于生成表单提交有效负载的MIME类型 由该算法生成。)
有关如何解释多部分/表单数据有效载荷的详细信息,请参阅RFC。 7578。[RFC7578] -HTML: The Living Standard
这肯定回答了我的问题,但是我对实现仍然有些困惑。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。