JavaScript 编码函数详解:escape、encodeURI 与 encodeURIComponent 的区别与用法
本文深入解析 JavaScript 中三种 URL 编码函数的区别。重点对比 escape、encodeURI 和 encodeURIComponent 的编码规则、保留字符处理及适用场景。指出 escape 已被废弃,推荐在完整 URL 编码时使用 encodeURI,在参数传递时使用 encodeURIComponent,并附带 Java 后端解码示例。
escape 函数的编码规则与现状
escape() 函数不会对 ASCII 字母、数字以及部分标点符号(包括 *、@、-、_、+、.、/)进行编码,其余所有字符均会被转换为转义序列。在大多数常规情况下,escape、encodeURI 和 encodeURIComponent 的编码结果表现一致。
当处理 Unicode 值超出 0-255 范围的字符时,escape 函数会输出 %u**** 格式的编码结果。
可以通过调用 unescape() 函数对经过 escape() 编码的字符串进行解码还原。
ECMAScript v3 标准已明确反对使用 escape() 方法,官方建议开发者改用 decodeURI() 和 decodeURIComponent() 来处理相关需求。
encodeURI 与 encodeURIComponent 的区别
接下来介绍 encodeURI 和 encodeURIComponent 两个函数。
encodeURI 和 encodeURIComponent 均定义于 ECMAScript-262 标准中,所有兼容该标准的语言(如 JavaScript、ActionScript)均实现了这两个函数。它们作为全局函数用于对 URI(遵循 RFC-2396 标准)字符串进行编码,但处理逻辑和应用场景存在差异。要理解二者的不同,需先了解 RFC-2396 中对 URI 字符的分类。
1. 保留字符(reserved characters):这类字符在 URI 中作为关键分隔符使用,包括:";"、"/"、"?"、":"、"@"、"&"、"="、"+"、"$"、","。
2. Mark 字符(mark characters):这类字符在 RFC-2396 中特别定义,虽未明确指定用途,但可能与其它 RFC 标准相关。包括:"-"、"_"、"."、"!"、"~"、"*"、"'"、"("、")"。
3. 基本字符(alphanum characters):构成 URI 主体部分,包含所有大写字母、小写字母和数字。
基于上述三类字符的分类,可以清晰解释 encodeURI 和 encodeURIComponent 函数的具体差异。
encodeURI 函数会对传入字符串中除基本字符、Mark 字符和保留字符之外的所有非 ASCII 字符进行转义编码。需要转义的字符会按照 UTF-8 编码规则,转换为一个、两个或三个字节的十六进制转义序列(格式为 %xx)。例如,空格字符 " " 会被转换为 "%20"。在此编码模式下,需编码的 ASCII 字符由一个字节转义字符替代,Unicode 值在 \u0080 到 \u007ff 之间的字符由两个字节转义字符替代,其余 16 位 Unicode 字符由三个字节转义字符替代。
encodeURIComponent 的处理方式与 encodeURI 仅有一点不同:它会对保留字符也进行转义编码。这种机制确保 URL 中的参数和值不会被 # 等特殊字符意外截断。例如,对于 URL:http://localhost:8080/xss/XssServlet?username=A&T Plastic,若直接传递,后端获取的 username 值仅为 "A",而非预期的 "A&T Plastic"。这是因为参数中包含保留字符 & 且未编码,导致值被截断。
String username = request.getParameter("username");
获取到的 username 值为 A,而非预期的 A&T Plastic。由于 username=A&T Plastic 包含未编码的保留字符 &,导致值被截断。正确做法是进行编码:encodeURIComponent("A&T Plastic") 结果为 A%26T%20Plastic,并据此修改连接字符串。
http://localhost:8080/xss/XssServlet?username=A%26T%20Plastic,此时后端即可正确获取 username 值为 A&T Plastic。
由此可见,当 username 的值包含 URI 保留字符时,必须进行编码处理。
例如,字符 ":" 会被转义字符 "%3A" 替代。
之所以存在这两个不同的函数,是因为在编写 JS 代码时,对 URI 的编码处理有两种不同需求。encodeURI 适用于对完整的 URI 字符串进行编码;而 encodeURIComponent 则用于对 URI 的某一部分进行编码,从而允许该部分包含 URI 保留字符。这在日常编程中非常实用。例如以下 URI 字符串:
http://www.mysite.com/send-to-friend.aspx?url=http://www.mysite.com/product.html
在上述 URI 字符串中,send-to-friend.aspx 页面会生成包含 HTML 格式邮件内容的链接,该链接地址即为 URI 中的 url 参数值。显然,url 值是 URI 的一部分,且内部包含了 URI 保留关键字符。因此,必须调用 encodeURIComponent 对其进行编码后使用,否则浏览器会将该 URI 视为无效。
经过正确编码后的 URI 应如下所示:
http://www.mysite.com/send-to-friend.aspx?url=http%3A%2F%2Fwww.mysite.com%2Fproduct.html
编码函数的实际应用场景
在实际应用中,encodeURIComponent 使用频率最高。它负责将中文、韩文等特殊字符转换为 UTF-8 格式的 URL 编码。因此,若通过 encodeURIComponent 向后端传递参数,后端需具备对 UTF-8 的支持(确保 form 表单的编码方式与当前页面编码方式一致)。
escape 函数不编码的字符共有 69 个:*,+,-,.,/,@,_,0-9,a-z,A-Z。
encodeURI 函数不编码的字符共有 82 个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z。
encodeURIComponent 函数不编码的字符共有 71 个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z。
各函数不编码字符对比
具体示例如下:
alert(encodeURIComponent("A&T Plastic")); //A%26T%20Plastic
alert(escape("A&T Plastic")); //A%26T%20Plastic
alert(encodeURI("A&T Plastic")); //A&T%20Plastic
alert(escape("A&T Plastic中")); //A%26T%20Plastic%uFFFD%uFFFD
从输出可见,encodeURI 未对 URI 的保留字符 & 进行编码,且中文字符 '中' 被编码为 %uFFFD%uFFFD。
而 encodeURIComponent 则对保留字符 & 进行了编码。
编码在安全与后端交互中的应用
URL 编码常被用于 XSS 攻击中,通过伪装具有威胁的 URL 来绕过服务端 xss filter,诱导不明用户点击。
因此,若仅处理 GET 提交时 URL 地址中的乱码问题,可以使用 encodeURI 来编码整个 URL。
若参数中含有保留字符需要进行编码,则应使用 encodeURIComponent 来编码部分参数。
若使用 encodeURIComponent 处理中文乱码,前端需执行两次 encodeURIComponent(encodeURIComponent('你好')),Java 后端使用:
java.Net.URLDecoder.decode(param,"UTF-8");
进行解码;
参考:
https://www.jb51.net/article/22880.htm
总结
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对本站的支持。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
