当字符串附加到
FormData
对象并发送到 Laravel 服务器时,谁决定将使用的编码?我们如何确保客户端报告的字符串长度与我们在服务器上获取的字符串长度匹配,并且不会因控制字符(尤其是换行符)而改变(\r\n
vs \n
)?
我正在
POST
构建我的模型对象,其中包括它的描述,即一个字符串(最多:1000 个字符),使用 axios
从我的 SPA (Vue 3 + Vuetify + TS) 到后端 Laravel服务器的 API 端点。验证在客户端和服务器端均已到位。在该前端,此描述显示在 v-textarea
中,报告内容正好有 1000 个字符,包括 8 个换行符。然后,使用 POST
对象将该描述与其他数据(包括图像)一起FormData
发送到服务器。
在服务器端,接收到的该字符串长度为 1008 个字符,而不是 1000 个字符,这会导致验证规则失败。检查字符串的客户端和服务器端版本后,唯一的区别是这些换行符在某个时刻已从
\n
转换为 \r\n
。我只是在寻找如何避免这种转换或至少使客户端和服务器端报告的长度匹配。
您遇到的行为源于换行符 ( )在通过 HTTP 传输时,在FormData 的编码和解码过程中进行处理。以下是原因和可能的解决方案的详细说明:
为什么会出现差异 1- FormData 和多部分编码:
当字符串附加到 FormData 对象并通过 HTTP 传输时,浏览器通常使用 multipart/form-data 内容类型。 FormData 的编码过程可能会引入换行符 ( ) 表示,通常将它们转换为回车+换行序列 ( )以与某些标准或平台兼容。 2- 服务器处理:
当 Laravel 处理传入请求时,它会读取 HTTP 请求正文提供的数据。换行序列 ( ) 被保留,并且测量字符串的长度,包括这些字符。 3-长度验证:
PHP 中的 strlen 函数(Laravel 内部使用)计算所有字节,包括额外的回车符 ( ) 在编码过程中引入。
确保长度报告一致的解决方案
选项 1:在客户端标准化换行符 在将字符串附加到 FormData 对象之前,替换所有换行符 ( ) 与 匹配服务器端表示:
打字稿
const description = textareaContent.replace(/\n/g, '\r\n');
formData.append('description', description);
选项 2:在服务器端标准化换行符 在 Laravel 中,您可以在接收字符串之后但在验证它之前规范换行符。例如,您可以使用 str_replace 函数来转换 返回 :
php
$request->merge([
'description' => str_replace("\r\n", "\n", $request->input('description')),
]);
这确保了长度验证符合客户端的期望。
选项3:调整验证规则
如果不希望修改内容,您可以调整服务器端验证以考虑潜在的问题 序列。例如,如果换行符是唯一的区别:
php
$description = $request->input('description');
$normalizedLength = strlen(str_replace("\r\n", "\n", $description));
if ($normalizedLength > 1000) {
return response()->json(['error' => 'Description exceeds the maximum length.'], 422);
}
选项 4:使用 JSON 而不是 FormData 如果您的应用程序可行,请考虑将数据作为 JSON 而不是 FormData 发送。 JSON 编码不会改变换行符( 遗迹 ):
打字稿
axios.post('/api/endpoint', {
description: textareaContent,
otherData: 'value',
}, {
headers: {
'Content-Type': 'application/json',
},
});
这完全避免了这个问题,因为没有 转换发生了。
推荐 为了易于实现和行为一致,在客户端标准化换行符(选项 1)是最直接的解决方案。但是,您可以将其与服务器端规范化(选项 2)结合起来,以便在客户端行为可能发生变化的情况下进行稳健处理。