当使用 POST 发送时,FormData 文本区域会放置 \r(回车符)

har*_*gim 4 html javascript form-data

为什么要FormData在换行符之前插入回车符?

当我使用 发送 post 请求时FormData,它使用 CRLF 行结尾,即使 textarea 的值根本没有回车符。这使得我的字符长度验证意外失败。

FormData下面的示例代码显示了 textarea 字符串值、输入的数据和将提交的编码数据之间的差异。JSON.stringify()用于转义控制字符。

document.getElementById('HistoryValue').textContent = JSON.stringify(document.forms.CRLFSample.history.value);
const fd = new FormData(document.forms.CRLFSample);
document.getElementById('FormData').textContent = JSON.stringify(fd.get('history'));
new Response(fd).text().then(text =>
document.getElementById('POSTData').textContent = JSON.stringify(text));
Run Code Online (Sandbox Code Playgroud)
#CRLFSample {
  width: 90%;
}
Run Code Online (Sandbox Code Playgroud)
<form id="CRLFSample" method="POST">
  <textarea name="history">
    line 1
    line 2
  </textarea>
</form>
<dl>
<dt>Textarea</dt><dd id="HistoryValue"></dd>
<dt>FormData</dt><dd id="FormData"></dd>
<dt>POST data</dt><dd id="POSTData"></dd>
</dl>
Run Code Online (Sandbox Code Playgroud)

以上已在 macOS 10.14 & 12 和 Android 10 上的 Firefox 92-94 和 Chrome 95 中进行了测试。注意“Textarea”显示换行符“\n”,但“POSTData”显示“\r\n”。“FormData”显示不同的结果主要取决于浏览器,大多数版本的 FireFox 仅显示“\n”,大多数版本的 Chrome 显示“\r\n”。

以下由原提问者编辑

没想到我有这么多评论。感谢您的关注,并请允许我对没有遵守网站指南表示歉意。我将尝试详细说明,以最好地帮助您重现错误并了解发生了什么。

我在我的 mac Catalina 10.15.7 上测试了这个,我的浏览器是 chrome 版本 95.0.4638.69(官方版本)(x86_64)。

下面是我尝试使用 formdata 验证字符长度并分别获取 textarea 的值。

let formData = new FormData(document.getElementById('form'));
let historyEl = document.getElementById('id_history');
console.log(formData.get('history').length, formData.get('history').includes('\r\n'));
console.log(historyEl.value.length, historyEl.value.includes('r\n'));
Run Code Online (Sandbox Code Playgroud)
<form id="form" method="POST">
<textarea class="materialize-textarea" cols="40" name="history" id="id_history" rows="10">    Lorem Ipsum is simply dummy text of the printing and typesetting 
industry. 
Lorem Ipsum has been the industry's standard dummy text ever since 
the 1500s, 
when an unknown printer took a galley of type and scrambled it to 
make a type 
specimen book. It has survived not only five centuries, but also 
the leap into electronic 
typesetting, remaining essentially unchanged. It was popularised in 
the 190
.</textarea>
</form>
Run Code Online (Sandbox Code Playgroud)

通过运行代码片段可以看到,formdata 的长度history显示的长度与 textarea 元素值的长度不同。

最初我从Windows用户那里收到了textarea值,我认为这只是操作系统的问题。但是当我检查它时,这种情况甚至发生在我的操作系统中,尤其是在使用表单数据提交时。

有人可能会问我可以检查 textarea 值的长度,但我尽量避免这样做,因为检查 formdata 是前端验证的全部要点。

我的母语不是英语,我的字符长度验证是在其他非拉丁语言上进行的,但有些东西阻止我在代码片段中发布非拉丁语言。但由于控制台分别产生不同的长度,我相信您无论如何都会通过其他字符得到这个想法。

out*_*tis 8

根据 MDN,使用由RFC 2388FormData指定的“multipart/form-data”格式,其中第 3 节指出:

\n
\n

媒体类型 multipart/form-data 遵循 RFC 2046 中概述的所有多部分 MIME 数据流的规则。

\n
\n

RFC \xc2\xa7 4.1.1,有关行结尾的部分指出:

\n
\n

任何 MIME“文本”子类型的规范形式必须始终将换行符表示为 CRLF 序列。

\n
\n

这就是为什么行尾在发布时被编码为 CRLF 的原因。从中尚不清楚的是,在FormData\ 的条目中是否应将行结尾编码为 CRLF(如 的结果所示formData.get(\'history\'))。

\n

规范没有提及添加条目或值时对行结尾进行编码FormData添加值时唯一的处理是针对Blob(即二进制)和File对象。FormData.get()没有提到对值的处理。严格来说,Chrome 的行为(存储在 中的编码值FormData)是非标准的。但是,直接存储值意味着将使用浏览器的内部(可能是平台的)行结束编码,这可能会有所不同。

\n

Fetch标准指定Response负责处理多部分/表单数据编码;具体来说,提取 FormData应该使用“multipart/form-data”编码算法

\n