我应该使用encodeURI还是encodeURIComponent来编码URL?


281

应该使用这两种方法中的哪一种来编码URL?



13
一个主要的不同是encodeURI不会进行编码/encodeURIComponent("ac/dc")=> ac%2FdcencodeURI("ac/dc")=>ac/dc

这可能会有所帮助: "encodeURIComponent() and encodeURI() encode a URI by replacing URL reserved characters with their UTF-8 encoding....They differ because encodeURI does not encode queryString or hash values...URLs do not allow many special characters, like spaces or slashes. However these special characters are part of life, so URL encoding was invented." 来源
user1063287

另请参见标题encodeURIComponent differs from encodeURI as follows为: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…的
user1063287

Answers:


324

这取决于您实际想要做什么。

encodeURI假定输入是一个完整的URI,其中可能包含一些需要编码的字符。

encodeURIComponent将对具有特殊含义的所有内容进行编码,因此您可以将其用于URI的组件,例如

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);

108

如果您要编码要放入URL组件的字符串(querystring参数),则应调用encodeURIComponent

如果您要编码现有的URL,请致电encodeURI


1
如果我使用的是Ajax,如何解码传递给php的网址?
Aditya Shukla 2010年

6
你不知道 网络服务器会自动执行此操作。
昆汀2010年

@Aditya:这取决于您在做什么。
SLaks 2010年

@slaks。我正在通过get传递参数,所以我想在php中检索它们。
Aditya Shukla 2010年

2
好。当我说Web服务器可以做到时,我可能会急促地说,但是无论您使用什么库来读取表单数据,都可以为您解决。
昆汀2010年

46

xkr.us进行了精彩的讨论,并附带示例。引用他们的总结:

escape()方法不对+字符进行编码,该字符被解释为服务器端的空格,也不由表单的字段中带有空格的表单生成。由于此缺点以及该函数无法正确处理非ASCII字符的事实,应尽可能避免使用escape()。最好的替代方法通常是encodeURIComponent()。

escape()将不会编码:@ * / +

相对于escape()而言,encodeURI()方法的使用更为专业,因为它对URI进行编码,而不是作为URL一部分的查询字符串。当您需要编码要用于任何使用URI且需要某些字符保持未编码状态的资源的字符串时,请使用此方法。请注意,此方法不对'字符进行编码,因为它是URI中的有效字符。

encodeURI()将不会编码:〜!@#$&*()=:/,;?+'

最后,在大多数情况下,当对URI的单个组件进行编码时,应使用encodeURIComponent()方法。此方法将对某些字符进行编码,这些字符通常会被识别为URI的特殊字符,因此可以包括许多组件。请注意,此方法不对'字符进行编码,因为它是URI中的有效字符。

encodeURIComponent()不会编码:〜!*()'


最近了解到。TOMCAT 9服务器更特别地说明了可以发送到URL的内容。当您需要编码的地方有“空格”时,encodeURIComponent()似乎会更好地工作。Tomcat 8不在乎,但9更特别。
Aggie Jon

因此,换句话说,encodeURI如果您尝试将文件名转换为URL并且文件名包含其中#,则失败
gman

17

这是一个摘要。

  1. escape()不会对@ * _ +-进行编码。/

    不要使用它。

  2. encodeURI()将不会对AZ az 0-9进行编码;,/?:@&= + $-_。!〜*'()#

    当您输入的是完整网址(例如“ https://searchexample.com/search?q=wiki ”)时,请使用它

  3. encodeURIComponent()将不会对AZ az 0-9-_进行编码。!〜*'()当您输入的内容是完整URL的一部分时使用它,例如 const queryStr = encodeURIComponent(someString)

1
这是一个很好的答案,因为它可以准确地告诉他们他们在做什么。但是我仍然有一个疑问,关于我应该使用什么以及何时使用。如果我的URI组件是完整的URL怎么办?然后我应该从上方使用规则2还是规则3,还是像编码URIComponent(encodeURI(theCompleteURI))一样使用
Panu Logic

10

encodeURIComponent():假定其参数是URI的一部分(例如协议,主机名,路径或查询字符串)。因此,它转义了用于分隔URI部分的标点符号。

encodeURI():用于对现有网址进行编码


7

encodeURI和之间的区别encodeURIComponent

encodeURIComponent(value)主要用于对queryString参数值进行编码,并且对中的所有适用字符进行编码valueencodeURI忽略协议前缀(http://)和域名。


在非常非常少见的情况下,当您想实现手动编码来对其他字符进行编码(尽管在典型情况下不需要编码)时! *,可以使用:

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

来源


6
您不应该在url中转义那些字符。
Arashsoft

正如引用的文档所说:“这些字符没有正式的URI划定用途”
caesarsol

@caesarsol所以,我应该编辑我的答案。让我知道您的想法,因为我无法理解引用的文档的含义
。– T.Todua

它只是对这些字符进行编码而没有用,除非您在正常的URL编码用例之外进行其他操作:)
caesarsol

2

其他答案描述了目的。以下是每个函数实际转换的字符:

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

上面的所有字符都将转换为十六进制百分比代码。空格到%20,百分比空格到,%25等等。下面的字符不变。

以下是函数不会转换的字符:

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )

-4

作为一般规则使用encodeURIComponent。不用担心长名称,因为它在使用中更具体,对我而言,这是更常用的方法。另外,不要迷恋使用encodeURI,因为您已经对其进行了测试并且似乎编码正确,这可能不是您要使用的,即使您在名字字段中使用“ Fred”进行的简单测试也可以使用,您仍会发现稍后,当您使用更高级的文本(例如添加与号或井号)时,它将失败。您可以查看其他答案,以了解其原因。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.