decodeURIComponent和decodeURI有什么区别?

465

decodeURIComponentdecodeURI之间有什么区别?

8个回答

485
为了解释这两者之间的差异,让我先解释一下encodeURIencodeURIComponent的区别。
主要区别在于:
- encodeURI函数旨在用于整个URI。 - encodeURIComponent函数旨在用于URI组件——也就是位于分隔符(; / ? : @ & = + $ , #)之间的任何部分。
因此,在encodeURIComponent中,这些分隔符也会被编码,因为它们被视为文本而不是特殊字符。
现在回到解码函数之间的区别,每个函数都解码其相应编码对应生成的字符串,并考虑特殊字符及其处理的语义。

9
另一个重要的区别在于,unescape函数不处理多字节的UTF-8序列,而decodeURI[Component]函数会处理:decodeURIComponent("%C3%A9") == "é"; unescape("%C3%A9") == "é"; - chris
4
我认为提供一些例子会非常有用。 - transang
请注意,decodeURI("%C3%A9") == "é"。除非您有特定的原因不允许编码application/x-www-form-urlencoded,否则decodeURI()将是最佳选择,因为浏览器通常会将数据发送为application/x-www-form-urlencoded。最常见的区别是处理+ - Mikko Rantalainen
可以使用encodeURIComponent()来处理所有内容,但始终要使用decodeURI()进行解码。对于encodeURIComponent()的输出,无论您使用decodeURI()还是decodeURIComponent()都没有关系。如果您需要处理浏览器发出的查询字符串,则正确解析可能需要使用decodeURI()而不是decodeURIComponent() - Mikko Rantalainen

134

encodeURIComponent/decodeURIComponent()是在URI中拼接和分解文本字符串时几乎总是需要使用的一对函数。

encodeURI很少使用,而且名称具有误导性:实际上应该叫做fixBrokenURI。它接受一个几乎是URI但包含无效字符(例如空格)的内容,并将其转换为真正的URI。它用于修复来自用户输入的无效URI,也可用于将带有裸Unicode字符的IRI(URI)转换为普通的URI(使用%-escaped UTF-8编码非ASCII字符)。

与encodeURI应该真正被称为fixBrokenURI()不同,decodeURI()也可以被称为可能破坏我以前工作的URI()。我想不出任何合理的用途; 请避免使用。


12
decodeURI(encodeURI('%20 ')) 在IE、Chrome和Firefox中都能正确地返回'%20 ',我想知道你在哪个浏览器/版本中观察到了不正确的结果? - ccppjava
1
可能在2009年时出现了问题,但现代浏览器在此期间已经赶上了(我猜测)。 - WoodrowShigeru

82
js> s = "http://www.example.com/string with + and ? and & and spaces";
http://www.example.com/string with + and ? and & and spaces
js> encodeURI(s)
http://www.example.com/string%20with%20+%20and%20?%20and%20&%20and%20spaces
js> encodeURIComponent(s)
http%3A%2F%2Fwww.example.com%2Fstring%20with%20%2B%20and%20%3F%20and%20%26%20and%20spaces

看起来 encodeURI 可以通过编码空格和其他一些字符(例如不可打印字符)生成“安全”的 URI,而 encodeURIComponent 会额外编码冒号、斜杠和加号字符,并且适用于查询字符串。特别需要注意的是 + 和 ? 和 & 的编码,因为在查询字符串中它们都是特殊字符。


37

由于我有同样的问题,但在这里没有找到答案,所以我进行了一些测试,以便弄清楚实际的区别是什么。

我这样做是因为我需要编码用于某些不涉及URL/URI的东西。

  • encodeURIComponent("A") 返回 "A",它不会将 "A" 编码为 "%41"
  • decodeURIComponent("%41") 返回 "A"。
  • encodeURI("A") 返回 "A",它不会将 "A" 编码为 "%41"
  • decodeURI("%41") 返回 "A"。

-这意味着两者都可以解码字母数字字符,即使它们没有对它们进行编码。然而...

  • encodeURIComponent("&") 返回 "%26"。
  • decodeURIComponent("%26") 返回 "&"。
  • encodeURI("&") 返回 "&"。
  • decodeURI("%26") 返回 "%26"。

尽管 encodeURIComponent 不会对所有字符进行编码,但 decodeURIComponent 可以解码 %00 到 %7F 之间的任何值。

注意:似乎如果您尝试解码一个大于%7F的值(除非它是Unicode值),那么您的脚本将会因为“URI错误”而失败。

注意:第一个decodeURIComponent中有一个拼写错误(m而不是n)。我无法更正它,因为我必须编辑至少6个字符。 - SuperNova
换句话说,如果解码后的字节不构成有效的UTF-8序列,则解码函数将抛出异常。一旦超过%7F,就会进入多字节序列。因此,例如%D0%B0是有效的,但%80则不是。 - David42

31

encodeURIComponent()

将输入转换为URL编码的字符串

encodeURI()

URL编码输入,但假定提供了完整的URL,因此通过不编码协议(例如http://)和主机名(例如www.stackoverflow.com)返回有效的URL。

decodeURIComponent()decodeURI() 是上述操作的相反操作。


15

decodeURIComponent函数用于解码 URI 中的特殊标记,例如 &, ?, # 等等,而decodeURI则不会。


6

0

编码 URI:

encodeURI() 方法不会对以下内容进行编码:

, / ? : @ & = + $ * #

例子

URI: https://my test.asp?name=ståle&car=saab
Encoded URI: https://my%20test.asp?name=st%C3%A5le&car=saab

编码URI组件:

encodeURIComponent()方法还会对以下内容进行编码:

, / ? : @ & = + $ #

例子

URI: https://my test.asp?name=ståle&car=saab
Encoded URI: https%3A%2F%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab

更多信息:W3Schoools.com


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