← 返回首页 📖 工具指南

URL 编码(百分号编码)完全指南

发布日期:2026年6月22日 | 阅读时间:7分钟

你是否遇到过这样的情况:URL 中的中文参数变成了看不懂的乱码,或者精心构造的 API 请求因为特殊字符而失败?这些问题的根源都在于 URL 编码。本文将彻底讲清楚 URL 编码的一切。

为什么需要 URL 编码?

URL(统一资源定位符)在设计之初只允许使用 ASCII 字符集中的部分字符。具体来说,URL 只能安全地包含:

任何超出这个范围的字符——包括中文、空格、&、=、# 等——都必须经过编码才能安全地放入 URL 中。这个编码过程就是 URL 编码,也叫百分号编码(Percent Encoding)。

URL 编码的原理

URL 编码的规则非常简单:将每个需要编码的字符转换为它的 UTF-8 字节序列,然后将每个字节表示为 %XX 的格式,其中 XX 是字节的十六进制值。

示例:空格

原始字符: 空格
ASCII 码:  32
十六进制:  20
URL 编码:  %20(传统形式)或 +(表单编码形式)

示例:中文字符

原始字符: 你
UTF-8 编码: E4 BD A0(3个字节)
URL 编码:  %E4%BD%A0

这就是为什么中文 URL 会变成一长串 % 开头的东西——每个中文字符在 UTF-8 中占 3 个字节,编码后就变成了 3 个 %XX。

JavaScript 中的 URL 编码

JavaScript 提供了三个编码函数,它们的行为有微妙但重要的差异:

encodeURIComponent():编码一切

编码除了字母、数字和 - _ . ! ~ * ' ( ) 之外的所有字符。这是编码 URL 参数值的正确选择:

encodeURIComponent("你好 world!")
// → "%E4%BD%A0%E5%A5%BD%20world!"
// 空格→%20,中文→UTF-8字节的%形式,! 被保留

encodeURI():保留 URL 结构

与 encodeURIComponent 类似,但会保留 URL 中的特殊字符(如 / ? & = #)。适合编码完整的 URL而非单个参数:

encodeURI("https://example.com/搜索?q=你好")
// → "https://example.com/%E6%90%9C%E7%B4%A2?q=%E4%BD%A0%E5%A5%BD"
// / ? = 等 URL 结构字符被保留,中文路径被编码

escape():已废弃,不要用

旧的编码函数,不处理 + @ / 等字符,且编码方式与现代标准不同。绝对不要在新代码中使用。

速查表

场景使用示例
编码 URL 参数值encodeURIComponent()?q=你好
编码完整 URLencodeURI()https://...
编码路径段encodeURIComponent + 手动替换%2F/users/张三

最常见的 URL 编码错误

错误 1:用 encodeURI 编码参数值

// ❌ 错误:& 和 = 不会被编码
const url = "https://api.com/search?q=" + encodeURI("a=1&b=2");
// 结果: https://api.com/search?q=a=1&b=2
// 服务器会解析成两个参数:q=a 和 b=2

// ✅ 正确
const url = "https://api.com/search?q=" + encodeURIComponent("a=1&b=2");
// 结果: https://api.com/search?q=a%3D1%26b%3D2

错误 2:重复编码

// ❌ 对已经编码的值再次编码
const encoded = encodeURIComponent("你好");  // %E4%BD%A0%E5%A5%BD
const doubleEncoded = encodeURIComponent(encoded); // %25E4%25BD...
// % 被编码成了 %25!

// ✅ 解码前先检查是否已被编码
function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch {
    return str; // 已经不是合法的编码格式
  }
}

错误 3:混淆 application/x-www-form-urlencoded 和 URL 编码

表单数据的编码格式和 URL 的编码格式不是同一回事

如果你的后端期望 x-www-form-urlencoded 格式,你需要确保空格被编码为 + 而非 %20。

实战场景

1. 构建带查询参数的 API URL

function buildURL(base, params) {
  const query = Object.entries(params)
    .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))
    .join('&');
  return base + '?' + query;
}

buildURL("https://api.com/search", {
  q: "Vue.js 教程",     // → q=Vue.js%20%E6%95%99%E7%A8%8B
  page: 1,
  sort: "created_at"
});

2. RESTful API 中的中文路径

// ❌ 直接拼接,可能产生非法 URL
fetch(`/users/${username}`);  // username = "张三"

// ✅ 对路径段编码
fetch(`/users/${encodeURIComponent(username)}`);
// → /users/%E5%BC%A0%E4%B8%89

3. 在 HTML 属性中使用 URL

// href 中的 & 必须转义为 &
<a href="/search?q=vue&page=2">Next</a>

// 但 JavaScript 中不需要
element.href = "/search?q=vue&page=2";  // ✅ 正确

HTML 实体编码 vs URL 编码

这是两种完全不同的编码,千万别搞混:

在 HTML 的 href 属性中,这两种编码可能会同时出现,理解它们的区别至关重要。

使用我们的 URL 编解码工具

在线 URL 编解码器支持:

立即体验使用 URL 编解码器

总结

本文最后更新于 2026年6月26日