decodeURIComponent vs unescape,unescape出了什么问题?

时间:2009-03-06 15:51:50

标签: javascript encoding escaping dhtml

在回答另一个问题时,我意识到我的Javascript / DOM知识已经过时了,因为我仍在使用escape / unescape对URL组件的内容进行编码,而它出现了我现在应该使用encodeURIComponent / decodeURIComponent代替。

我想知道的是escape / unescape出了什么问题?有一些模糊的建议,围绕Unicode字符存在某种问题,但我找不到任何明确的解释。

我的网络体验相当有偏见,几乎所有这些都是编写与Internet Explorer绑定的大型Intranet应用程序。这涉及大量使用escape / unescape,所涉及的应用程序已经完全支持Unicode多年了。

那么escape / unescape应该具有哪些Unicode问题?有没有人有任何测试用例来证明这些问题?

4 个答案:

答案 0 :(得分:40)

  

我想知道的是escape / unescape出了什么问题?

它们并非“错误”,它们只是它们自己的特殊字符串格式,看起来有点像URI参数编码,但实际上并非如此。特别是:

  • '+'表示加号,而不是空格
  • 有一种特殊的“%uNNNN”格式,用于编码Unicode UTF-16代码点,而不是编码UTF-8字节

因此,如果使用escape()创建URI参数值,则对于包含加号或任何非ASCII字符的字符串,将得到错误的结果。

escape()可以用作内部JavaScript编码方案,例如转义cookie值。但是现在所有浏览器都支持encodeURIComponent(原来不是这种情况),没有理由优先使用escape。

我所知道的escape / unescape只有一个现代用途,这是通过利用URIComponent处理中的UTF-8处理来实现UTF-8编码器/解码器的快捷方式:

utf8bytes= unescape(encodeURIComponent(unicodecharacters));
unicodecharacters= decodeURIComponent(escape(utf8bytes));

答案 1 :(得分:9)

escape仅对0到255(ISO-8859-1)范围内的字符起作用(ISO-8859-1,它实际上是用单个字节表示的unicode代码点)。 (*)

encodeURIComponent适用于javascript可以表示的所有字符串(这是unicode基本多语言平面的整个范围,即unicode代码点0到1,114,111或0x10FFFF,几乎覆盖当前使用的任何人类书写系统)。

这两个函数都生成仅使用0到127(US-ASCII)代码点的url安全字符串,后者通过首先将字符串编码为UTF-8然后应用熟悉的%XX十六进制编码来完成escape,任何不是网址安全的代码点。

顺便提一下,为什么你可以在没有任何循环或垃圾生成的javascript中make a two-funcall UTF-8 encoder/decoder,通过组合这些原语来消除除{0}和unescape之外的所有UTF-8处理副作用。 {1}}版本反向执行相同操作。

(*)脚注:像谷歌Chrome这样的一些现代浏览器已被调整为生成%uXXXX,因为上面的255个字符范围的转义最初并未定义,但是对于解码该编码的Web服务器支持不是很好 - 实现解码IETF标准化的基于UTF-8的编码。

答案 2 :(得分:7)

最好的答案是,它正在本网站http://meyerweb.com/eric/tools/dencoder/

上在线工作
function decode() {
    var obj = document.getElementById('dencoder');
    var encoded = obj.value;
    obj.value = decodeURIComponent(encoded.replace(/\+/g,  " "));
}

答案 3 :(得分:5)

我遇到的另一个“现代”用法是解析URI编码的字符串,该字符串可能包含无效的UTF8字节序列。在某些情况下,decodeURIComponent可以抛出异常。您可能需要捕获此异常并回退到使用unescape。

一个例子是'tür'编码为't%FCr',我见过Firefox产生的(当字符被粘贴到地址栏后?)。