53

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

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

我的网络体验相当偏颇,几乎所有的人都在编写与 Internet Explorer 相关的大型 Intranet 应用程序。这涉及到大量使用escape/unescape并且所涉及的应用程序多年来一直完全支持 Unicode。

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

4

4 回答 4

44

我想知道 escape/unescape 有什么问题?

它们本身并没有“错误”,它们只是它们自己的特殊字符串格式,看起来有点像 URI-parameter-encoding 但实际上并非如此。尤其是:

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

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

escape() 可以用作内部纯 JavaScript 编码方案,例如转义 cookie 值。然而,既然所有浏览器都支持 encodeURIComponent (最初并非如此),没有理由优先使用转义。

我所知道的转义/取消转义只有一种现代用途,这是一种通过在 URIComponent 处理中利用 UTF-8 处理来实现 UTF-8 编码器/解码器的快速方法:

utf8bytes= unescape(encodeURIComponent(unicodecharacters));
unicodecharacters= decodeURIComponent(escape(utf8bytes));
于 2009-03-06T16:24:33.630 回答
11

escape仅对 0 到 255 范围内的字符(包括 ISO-8859-1,它是可用单个字节表示的有效 unicode 代码点)进行操作。(*)

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

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

这就是为什么您可以在 javascript 中制作一个双功能的 UTF-8 编码器/解码器而无需任何循环或垃圾生成的原因,通过组合这些原语来消除除 UTF-8 处理之外的所有副作用,就像unescapedecodeURIComponent版本一样反过来也一样。

(*) 脚注:一些现代浏览器(如 Google Chrome)已经过调整,以生成 %uXXXX 用于最初未定义的上述 255 个字符范围的转义,但 Web 服务器对解码该编码的支持并不像解码基于 IETF 标准化的 UTF-8 编码。

于 2012-10-07T20:36:37.620 回答
7

最好的答案是它在这个网站上在线工作http://meyerweb.com/eric/tools/dencoder/

function decode() {
    var obj = document.getElementById('dencoder');
    var encoded = obj.value;
    obj.value = decodeURIComponent(encoded.replace(/\+/g,  " "));
}
于 2013-11-16T01:00:16.580 回答
7

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

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

于 2011-10-11T12:52:54.260 回答