nodejs 部分数据仅来自 firefox
nodejs partial data just from firefox
我在 nodejs 上有一个服务器 运行,我有以下代码来管理 post 请求 -
form.on('file', function (field, file) {
var RecordingInfo = JSON.parse(file.name);
...
当我尝试上传文件时出现以下异常:
undefined:1
"}
SyntaxError: Unexpected end of input
at Object.parse (native)
at IncomingForm.<anonymous> (.../root.js:31:34)
...
searching around the web,我觉得这个异常是因为数据是按位来的,第一个位到达后触发事件,而我没有所有的数据。好的。问题是,经过一些测试后,我喜欢 chrome 我可以毫无问题地上传大文件(尝试了 1.75gb 的文件),而 firefox 使用 6kb 的文件会使服务器崩溃。
我的问题是 - 为什么它们不同?
可以从 here 下载示例捕获。第一个 post 来自 chrome,第二个来自 firefox.
上传前完整的file.name字符串为:
// chrome
"{"subject":"flksajfd","lecturer":"אבישי וינר","path":"/גמרא","fileType":".png"}"
// firefox
"{"subject":"fdsa","lecturer":"אלקס ציקין","path":"/גמרא","fileType":".jpg"}"
(提交的数据不一样,不过我觉得无所谓)
Chrome 将 JSON 编码的 "filename" 中的双引号编码为 %22
,而 Firefox 将它们编码为 \"
.
您的文件上传解析库,Formidable, explicitly truncates the filename from the last \
character。它期望双引号被编码为 %22
尽管 RFC 2616 允许反斜杠转义引号,就像 Firefox 已经实现的那样。您可以认为这是 Formidable 中的错误。结果是以下 JSON 字符串:
'{"subject":"fdsa",...,"fileType":".jpg"}'
...编码如下:
'{%22subject%22:%22fdsa",...,%22fileType%22:%22.jpg%22}' // Chrome
'{\"subject\":\"fdsa\",...\"fileType\":\".jpg\"}' // Firefox
...然后由 Formidable 解码:
'{"subject":"fdsa",..."fileType":".jpg"}' // Chrome
'"}' // Firefox
要解决此问题,您有以下几种选择:
- Raise the issue with Formidable 正确处理反斜杠转义的引用值字符串(或自行修复并提交拉取请求)。
- 在
FormData
对象的单独部分发送 JSON 有效负载,例如using a Blob
.
- 将 JSON 格式文件名中的所有双引号字符音译为不会出现在字符串其他位置的 'safe' 字符(我选择
^
作为示例);替换引用客户端并在服务器端恢复它,如下所示。
客户:
var formData = new FormData();
formData.append('file', $scope.recording, JSON.stringify(RecordingInfo).replace(/"/g, '^');
服务器
form.on('file', function (field, file) {
var RecordingInfo = JSON.parse(file.name.replace(/\^/g, '"');
我在 nodejs 上有一个服务器 运行,我有以下代码来管理 post 请求 -
form.on('file', function (field, file) {
var RecordingInfo = JSON.parse(file.name);
...
当我尝试上传文件时出现以下异常:
undefined:1
"}
SyntaxError: Unexpected end of input
at Object.parse (native)
at IncomingForm.<anonymous> (.../root.js:31:34)
...
searching around the web,我觉得这个异常是因为数据是按位来的,第一个位到达后触发事件,而我没有所有的数据。好的。问题是,经过一些测试后,我喜欢 chrome 我可以毫无问题地上传大文件(尝试了 1.75gb 的文件),而 firefox 使用 6kb 的文件会使服务器崩溃。
我的问题是 - 为什么它们不同?
可以从 here 下载示例捕获。第一个 post 来自 chrome,第二个来自 firefox.
上传前完整的file.name字符串为:
// chrome
"{"subject":"flksajfd","lecturer":"אבישי וינר","path":"/גמרא","fileType":".png"}"
// firefox
"{"subject":"fdsa","lecturer":"אלקס ציקין","path":"/גמרא","fileType":".jpg"}"
(提交的数据不一样,不过我觉得无所谓)
Chrome 将 JSON 编码的 "filename" 中的双引号编码为 %22
,而 Firefox 将它们编码为 \"
.
您的文件上传解析库,Formidable, explicitly truncates the filename from the last \
character。它期望双引号被编码为 %22
尽管 RFC 2616 允许反斜杠转义引号,就像 Firefox 已经实现的那样。您可以认为这是 Formidable 中的错误。结果是以下 JSON 字符串:
'{"subject":"fdsa",...,"fileType":".jpg"}'
...编码如下:
'{%22subject%22:%22fdsa",...,%22fileType%22:%22.jpg%22}' // Chrome
'{\"subject\":\"fdsa\",...\"fileType\":\".jpg\"}' // Firefox
...然后由 Formidable 解码:
'{"subject":"fdsa",..."fileType":".jpg"}' // Chrome
'"}' // Firefox
要解决此问题,您有以下几种选择:
- Raise the issue with Formidable 正确处理反斜杠转义的引用值字符串(或自行修复并提交拉取请求)。
- 在
FormData
对象的单独部分发送 JSON 有效负载,例如using aBlob
. - 将 JSON 格式文件名中的所有双引号字符音译为不会出现在字符串其他位置的 'safe' 字符(我选择
^
作为示例);替换引用客户端并在服务器端恢复它,如下所示。
客户:
var formData = new FormData();
formData.append('file', $scope.recording, JSON.stringify(RecordingInfo).replace(/"/g, '^');
服务器
form.on('file', function (field, file) {
var RecordingInfo = JSON.parse(file.name.replace(/\^/g, '"');