本文详细解析JavaScript中encodeURI与encodeURIComponent两个全局函数的区别。两者均遵循ECMA-262标准,用于对URI字符串进行编码。主要差异在于对保留字符的处理:encodeURI保留分号、斜杠等结构字符,适用于完整URL编码;而encodeURIComponent会对所有非基本字符及保留字符进行转义,适用于URL参数值的编码。文章通过具体代码示例展示了两者在输出结果上的不同,并简要提及对应的解码函数。
encodeURI与encodeURIComponent的区别
encodeURI和encodeURIComponent均为ECMA-262标准定义的全局函数,所有符合该标准的语言(如JavaScript、ActionScript)均实现了这两个函数。它们用于对符合RFC-2396标准的URI字符串进行编码,但处理逻辑和应用场景存在差异。要理解二者的区别,需先了解RFC-2396中定义的字符分类。
保留字符(reserved characters):指URI中用于分割各部分的关键字符,包括分号(;)、斜杠(/)、问号(?)、冒号(:)、@、&、=、+、$和逗号(,)。
Mark字符(mark characters):在RFC-2396中特别定义但未明确用途的字符,可能与其他RFC标准相关,包括连字符(-)、下划线(_)、点(.)、感叹号(!)、波浪号(~)、星号(*)、单引号(')以及括号(())。
基本字符(alphanum characters):构成URI主体的字符,包含所有大写字母、小写字母和数字。
基于上述三类字符的分类,可以清晰解释encodeURI与encodeURIComponent函数的行为差异。
encodeURI函数会对输入字符串中除基本字符、Mark字符和保留字符之外的所有字符进行转义编码。需要转义的字符会按UTF-8编码转换为一个、两个或三个字节,并以十六进制转义序列(%xx)表示。例如,空格会被转换为%20。在此模式下,ASCII字符用一个字节转义,Unicode值在\u0080至\u007ff之间的字符用两个字节转义,其他16位Unicode字符则用三个字节转义。
encodeURIComponent的处理方式与encodeURI仅有一点不同:它会对保留字符也进行转义编码。例如,冒号(:)会被转换为%3A。
存在这两个不同函数的原因是JavaScript中对URI编码的两种不同需求。encodeURI适用于对完整的URI字符串进行编码,而encodeURIComponent则用于对URI中的特定部分(如查询参数)进行编码,使其能够包含原本属于保留字符的内容。这在日常编程中非常实用。例如,考虑以下URI字符串:
http://www.mysite.com/send-to-friend.aspx?url=http://www.mysite.com/product.html
在上述URI中,send-to-friend.aspx页面会生成包含链接的HTML邮件内容,该链接地址即为url参数的值。显然,url的值是URI的一部分,且内部包含了URI保留字符。如果直接使用该字符串,浏览器会将其视为无效URI。因此,必须调用encodeURIComponent对url部分进行编码后再使用。
http://www.mysite.com/send-to-friend.aspx?url=http%3A%2F%2Fwww.mysite.com%2Fproduct.html
示例
关于encodeURI
encodeURI编码示例
代码实现如下:
var uri="my test.asp?name=ståle&car=saab";
document.write(encodeURI(uri)); 上述代码的输出结果为:
my%20test.asp?name=st%C3%A5le&car=saab
关于encodeURIComponent
encodeURIComponent编码示例
另一段代码实现如下:
var uri="http://jb51.net/my test.asp?name=ståle&car=saab";
document.write(encodeURIComponent(uri)); 上述代码的输出结果为:
http%3A%2F%2Fjb51.net%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab
相关解码函数
补充说明
在ECMA-262标准中,还定义了与上述两个编码函数对应的解码全局函数:decodeURI和decodeURIComponent。可以使用它们来解码经过编码的字符串。