在 Web 开发中,URL 编码是一个常见需求,特别是在处理用户输入、API 请求参数或中文字符时。JavaScript 提供了三个用于编码字符串的函数:escape、encodeURI 和 encodeURIComponent。它们功能相似,但使用场景和编码规则有显著区别。
✅ 一句话总结
encodeURI用于编码完整的 URI,保留 URI 结构字符(如:、/、?);encodeURIComponent用于编码 URI 的组成部分(如参数值),会转义所有特殊字符;escape是已废弃的旧方法,不推荐使用。
✅ 一、核心区别概览
| 方法 | 用途 | 是否转义特殊字符 | 是否推荐使用 |
|---|---|---|---|
encodeURI() | 编码完整的 URI | ❌ 保留 #, ?, =, &, /, : 等 | ✅ 推荐 |
encodeURIComponent() | 编码 URI 的组成部分(如参数) | ✅ 转义几乎所有特殊字符 | ✅ 推荐 |
escape() | 旧式编码(已废弃) | 部分转义,使用 %u 编码 Unicode | ❌ 不推荐 |
✅ 二、详细解析
🔹 1. encodeURI(uri)
- 作用:对整个 URI进行编码,确保其格式合法。
- 特点:
- 不会对 URI 中具有特殊意义的字符进行编码,如:
:(协议分隔符)/(路径分隔符)?(查询参数开始)#(锚点)&,=,+(参数分隔符)
- 只编码非法字符(如空格、中文、引号等)。
- 不会对 URI 中具有特殊意义的字符进行编码,如:
- 适用场景:当你有一个完整的 URL 字符串,需要确保它在传输中合法。
📌 示例:
const url = "https://example.com/search?q=hello world&name=张三";
console.log(encodeURI(url));
// 输出:https://example.com/search?q=hello%20world&name=%E5%BC%A0%E4%B8%89
// 注意:?、=、&、:、/ 都未被编码
🔹 2. encodeURIComponent(uriComponent)
- 作用:对 URI 的某一部分(组件)进行编码。
- 特点:
- 会编码几乎所有特殊字符,包括:
- 空格 →
%20 ?,=,&,+,#,/,:,@等都会被编码;
- 空格 →
- 只有最基本的 ASCII 字母数字和
- _ . ! ~ * ' ( )不编码。
- 会编码几乎所有特殊字符,包括:
- 适用场景:编码查询参数的值或路径中的动态部分。
📌 示例:
const paramName = "user name";
const paramValue = "张三 & 李四";
console.log(encodeURIComponent(paramName));
// 输出:user%20name
console.log(encodeURIComponent(paramValue));
// 输出:%E5%BC%A0%E4%B8%89%20%26%20%E6%9D%8E%E5%9B%9B
// 注意:& 被编码为 %26
// 构建 URL
const finalUrl = `https://example.com/user?name=${encodeURIComponent(paramValue)}`;
🔹 3. escape(string)(已废弃)
- 作用:旧式的编码方法,不推荐使用。
- 编码规则:
- 对 ASCII 字符(0x00 - 0xFF)使用
%+ 两位十六进制(如空格 →%20); - 对 Unicode 字符(> 0xFF)使用
%u+ 四位十六进制(如“马” →%u9A6C);
- 对 ASCII 字符(0x00 - 0xFF)使用
- 问题:
%u格式不是标准的 URL 编码;- 不被现代浏览器和服务器广泛支持;
- 已被
encodeURI和encodeURIComponent取代;
- 替代方案:永远使用
encodeURI或encodeURIComponent。
📌 示例(仅作对比):
console.log(escape("hello 世界"));
// 输出:hello%20%u4E16%u754C (%u 格式非标准)
console.log(encodeURIComponent("hello 世界"));
// 输出:hello%20%E4%B8%96%E7%95%8C (标准 UTF-8 编码)
✅ 三、编码原理对比(以中文“马”为例)
| 字符 | Unicode 码点 | escape | encodeURI / encodeURIComponent |
|---|---|---|---|
| 马 | U+9A6C | %u9A6C | %E9%A9%AC |
escape:直接使用%u+ 四位十六进制码点;encodeURI/encodeURIComponent:- 将“马”转换为 UTF-8 字节序列:
0xE9 0xA9 0xAC; - 每个字节前加
%:%E9%A9%AC;
- 将“马”转换为 UTF-8 字节序列:
✅ 关键点:现代编码标准使用 UTF-8 +
%编码字节,而不是直接编码 Unicode 码点。
✅ 四、如何选择?
| 场景 | 推荐方法 |
|---|---|
| 编码完整的 URL 字符串 | encodeURI() |
| 编码查询参数的值或路径段 | encodeURIComponent() |
| 任何新项目 | 避免使用 escape() |
✅ 五、一句话总结
使用
encodeURI保护完整的 URL 结构,使用encodeURIComponent安全编码参数值。escape是过时的方法,应被彻底弃用。理解 UTF-8 编码原理是掌握现代 URL 编码的关键。
💡 进阶建议
- 在构建 URL 时,对每个参数值使用
encodeURIComponent; - 不要对整个 URL 使用
encodeURIComponent,否则:、/会被错误编码; - 解码时使用对应的
decodeURI和decodeURIComponent; - 在 Node.js 或现代浏览器中,优先使用
URLSearchParams处理查询参数:
const params = new URLSearchParams();
params.append('name', '张三');
params.toString(); // "name=%E5%BC%A0%E4%B8%89"