【发布时间】:2013-10-08 16:54:41
【问题描述】:
我有相当标准的 javascript/XHR 拖放文件上传代码,只是遇到了一个不幸的现实世界障碍。我的(Win7)桌面上有一个名为“TEST-é-TEST.txt”的文件。在 Chrome (30.0.1599.69) 中,它以 UTF-8 的文件名到达服务器,效果很好。在 Firefox (24.0) 中,文件名在到达服务器时似乎已损坏。
我不相信 Firebug/Chrome 可能会告诉我有关编码的内容,因此我检查了请求数据包的十六进制。除了非 ASCII 字符在两个浏览器中的编码确实不同之外,其他一切都相同:
Chrome: C3 A9 (this is the expected UTF-8 for that character)
Firefox: EF BF BD (UTF-8 "replacement character"?!)
这是 Firefox 的错误吗?我尝试重命名文件,将 é 替换为 ó,而 Firefox 十六进制是相同的……所以这样的 mangle 看起来真的像浏览器错误。 (例如,如果 Firefox 混淆地发送 ISO-8859-1,但不接触它,我会看到一个 E9 字节,我可以在服务器端处理它,但它不应该破坏它!)
不管是什么原因,我可以在客户端或服务器端做些什么来纠正这个问题吗?如果一个替换字符确实被发送到服务器,那么它在那里似乎无法恢复,所以我几乎肯定需要在客户端这样做。
是的,存在此代码的页面有charset=utf-8,Firefox 在查看>字符编码下确认它认为该页面为 UTF-8。
此外,如果我将文件名转储到console.log,它看起来还不错——我猜它只是在setRequestHeader("X-File-Name",file.name) 中/之后受到破坏。
最后,似乎传递给 setRequestHeader() 的值应该能够具有高达 U+00FF 的代码点,因此 U+00E9 (é) 和 U+00F3 (ó) 应该不会造成问题,虽然更高的代码可能会触发 SyntaxError:http://www.w3.org/TR/XMLHttpRequest2/#the-setrequestheader-method
【问题讨论】:
-
如果不知道 XHR 在您的情况下应该在哪里获取文件名,很难在这里说任何有用的东西。这是从哪里来的?
-
删除时,e.dataTransfer.files ...我没有尝试硬编码文件名来消除该变量。
-
我只是硬编码了文件名;相同的行为。 xhr.setRequestHeader("X-File-Name", "TEST-é-TEST.txt");
-
我认为这确实缩小了问题所在:Firefox 的 setRequestHeader() 实现,当您传递一个包含非 ASCII 值的值时。如何克服?
-
嗯。因此,查看 Firefox 中的 setRequestHeader,它正在按照规范中的说明进行操作:删除该 JSString 的每个 16 位单元的高字节并将低字节放入标头中。所以我不确定你为什么会在那里看到 EF BF BD。您应该看到的是 E9。您使用的是哪个 Firefox 版本?
标签: javascript google-chrome firefox utf-8 drag-and-drop