为什么unescape有效但decodeURI无效?

7
我有以下变量:

var string="Mazatl%E1n";

服务器返回的字符串是这样的。我想要做的就是将其解码为:Mazatlán。我尝试了以下方法:

var string="Mazatl%E1n";

alert(unescape(string));
alert(decodeURI(string));

unescape运行良好,但是我不想使用它,因为我知道它已经deprecated,所以我尝试了decodeURI,但是出现以下错误:

Uncaught URIError: URI malformed

为什么会这样?非常感谢任何帮助。

var string="Mazatl%E1n";

alert(unescape(string));
alert(decodeURI(string));


查看decodeURIComponent函数... - Heretic Monkey
1
escape()unescape()是为ISO字符串定义的。decodeURI()encodeURI()是为UTF-8字符串定义的。 - Johan Karlsson
3
@JohanKarlsson的方向是正确的。%E1是Unicode编码,但URIs使用UTF-8编码,因此正确的编码是%C3%A1。您可以通过运行encodeURIComponent("Mazatlán")来查看这一点。 - Heretic Monkey
3个回答

7
你遇到了这个错误是因为%E1是Unicode编码,而decodeURI()需要UTF-8编码。
你需要自己创建一个unescape函数,例如:

function unicodeUnEscape(string) {
  return string.replace(/%u([\dA-Z]{4})|%([\dA-Z]{2})/g, function(_, m1, m2) {
    return String.fromCharCode(parseInt("0x" + (m1 || m2)));
  })
}

var string = "Mazatl%E1n";
document.body.innerHTML = unicodeUnEscape(string);

或者您可以更改服务器,以便发送使用UTF-8编码的字符串,这种情况下您可以使用 decodeURI()

var string = "Mazatl%C3%A1n"
document.body.innerHTML = decodeURI(string);


你能否记录一下正则表达式的文档? - angelcool.net
1
它匹配一个%,后面跟着u和4个十六进制数字,或者是%后面跟着2个十六进制数字:https://regex101.com/r/cC4tN4/1 - Johan Karlsson
1
我建议@JohanKarlsson在正则表达式的g后面添加i(不区分大小写),因为%2f和%2F都是有效的编码。 - Noam Rathaus

2

URI支持ASCII字符集,对于á的正确格式编码是%C3%A1(使用UTF-8编码)。

fiddle


escape和unescape使用十六进制转义序列
(与其他方式不同..);
因此,您从服务器获取的值已使用escape(string)进行了编码。


1

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