仅在Firefox中,encodeURIComponent()的行为不同

11

我对文件名进行编码,并将其作为URL的一部分发送,例如/rest/get?name=Filename.txt。在JavaScript中,链接构建非常简单。


url = '/rest/get?name=' + window.encodeURIComponent(file.name);

它适用于简单情况,但对于严格的测试,我使用一个名为

的文件。

你好abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§!#¤%&()=`@£$€{[]}+´¨^~'-_,;.txt

URI编码后,我期望得到一个链接

/rest/get?name=%E4%BD%A0%E5%A5%BDabcABC%C3%A6%C3%B8%C3%A5%C3%86%C3%98%C3%85%C3%A4%C3%B6%C3%BC%C3%AF%C3%AB%C3%AA%C3%AE%C3%A2%C3%A9%C3%AD%C3%A1%C3%B3%C3%BA%C3%BD%C3%B1%C2%BD%C2%A7%3F%3FabcABC%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD!%23%C2%A4%25%26()%3D%60%40%C2%A3%24%E2%82%AC%7B%5B%5D%7D%2B%C2%B4%C2%A8%5E~%27-_%2C%3B.txt

我明白了。在最新版本的IE和Chrome中,构建的链接可以正常工作,但在Firefox中失败了。经过一些调查,我发现在Firefox中,encodeURIcomponent的工作方式不同。以下是Firefox的实际结果:

/rest/get?name=%3F%3FabcABC%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD%EF%BF%BD!%23%EF%BF%BD%25%26%28%29%3D%60%40%EF%BF%BD%24%3F{[]}%2B%EF%BF%BD%EF%BF%BD^~%27-_%2C%3B.txt

可视化比较(Chrome链接在左侧,Firefox链接在右侧):

Comparison

我还尝试将在 Chrome 中构建的有效链接复制并粘贴到 Firefox 中,结果可以正常使用。

为什么会得到不同的结果?
是否是 Firefox 中 encodeURIComponent() 的一个错误?
Firefox 是否使用不同的编码方式进行 encodeURIComponent()

更新。 我找到了类似的问题(encodeURIComponent 在中国各浏览器中表现不同 [搜索] 和 encodeURIComponent 在浏览器和 ä-ö-å 字符中的差异 [äöå]),但都没有答案。

更新2。 进一步调查发现以下字符被编码方式有所不同,并在服务器上导致“文件未找到”异常:

  • 你好
  • æøåÆØÅäöüïëêîâéíáóúýñ
  • ½§¤
  • £€


我猜测可能是因为FireFox的字体映射不同,或者FF用于JavaScript解释器的某些设置出了问题。 - durbnpoisn
1
%3F?,所以看起来它没有正确理解 Unicode。 - James Thorpe
@JamesThorpe 是的,你说得对。但是正如你所看到的,URL的另一部分也被以不同的方式编码,如果我从开头删除 你好,它仍然失败。 - naXa stands with Ukraine
你尝试过使用.escape()和.unescape()函数进行URI编码吗?https://jsfiddle.net/vx4e9mb7/ - idream1nC0de
@naXa 更新的 JSFiddle:https://jsfiddle.net/vx4e9mb7/1/ - idream1nC0de
escape()在JavaScript 1.5版之后已被弃用(http://www.w3schools.com/jsref/jsref_escape.asp)。 - Eduard Wirch
2个回答

1
我猜你的问题不是encodeURIComponent()方法,而是file.name的编码。请详细说明:如何初始化file.name?这些字符来自哪里?

从服务器接收到一个文件名列表。 - naXa stands with Ukraine
1
所以,你能确保(使用JS调试器),在传递给encodeURIComponent()之前,file.name中包含正确的字符(而不是问号)吗? - Eduard Wirch
@naXa,确实可以在开发者工具控制台中尝试使用encodeURIComponent("你好"),它会返回"%E4%BD%A0%E5%A5%BD",正如您所期望的那样。 - Nickolay

-1

encodeURIComponent()是一种本地函数,因此Firefox显然在底层使用了一些不同的实现。

如果你卡住了,那么只需提供自己的javascript实现encodeURIComponent(),然后你就可以在所有浏览器中获得相同的结果。这里有一个链接,告诉你如何获取该算法的开源副本:

encodeURIComponent算法源代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接