好,这个我给你一份真正“能避坑”的 JS URL 编码 / 解码完全指南。
不是只告诉你用哪个函数,而是什么时候该用谁、用错会出什么事,以及真实业务场景怎么选。
JS 对 URL 进行编码 / 解码完全指南
(encodeURI vs encodeURIComponent vs escape 全面对比)
一、为什么 URL 一定要编码?
URL 只能安全传输 ASCII 字符,但现实中我们经常遇到:
- 中文(
搜索=苹果手机) - 空格
& ? = # /- JSON、Base64、Token
如果不编码,可能会导致:
- ❌ 参数被截断
- ❌ 服务器解析错误
- ❌ XSS / 注入风险
- ❌ 浏览器自动“帮你改”,调试地狱
二、JS 中常见的 5 种方式(先给全景)
| 方法 | 是否推荐 | 用途 |
|---|---|---|
encodeURIComponent | ✅ 强烈推荐 | URL 参数值 |
decodeURIComponent | ✅ 必须配套 | 解码参数 |
encodeURI | ⚠️ 有场景 | 整个 URL |
decodeURI | ⚠️ 有场景 | 解整个 URL |
escape / unescape | ❌ 废弃 | 千万别用 |
三、最重要的两个(90% 场景)
1️⃣ encodeURIComponent(参数级编码,王者)
👉 只要是 URL 参数值,默认就用它
const keyword = "苹果 手机 & 华为";
const url = "https://example.com/search?q="
+ encodeURIComponent(keyword);
console.log(url);
// https://example.com/search?q=%E8%8B%B9%E6%9E%9C%20%E6%89%8B%E6%9C%BA%20%26%20%E5%8D%8E%E4%B8%BA
解码
decodeURIComponent("%E8%8B%B9%E6%9E%9C%20%E6%89%8B%E6%9C%BA");
// 苹果 手机
✅ 会编码:
- 空格
- 中文
& = ? # /
✅ 不会破坏 URL 结构
2️⃣ encodeURI(整条 URL 编码)
👉 用于“整条 URL 已拼好”的情况
const url = "https://example.com/search?q=苹果 手机";
console.log(encodeURI(url));
输出:
https://example.com/search?q=%E8%8B%B9%E6%9E%9C%20%E6%89%8B%E6%9C%BA
⚠️ 它不会编码这些字符:
: / ? & = #
❗ 如果参数值里本身就有 & 或 =,会直接炸。
四、encodeURI vs encodeURIComponent(核心对比)
| 对比点 | encodeURI | encodeURIComponent |
|---|---|---|
| 编码范围 | 少 | 多 |
会编码 & | ❌ | ✅ |
会编码 = | ❌ | ✅ |
| 适合对象 | 整条 URL | 参数值 |
| 安全性 | 中 | 高 |
| 实际推荐 | ⚠️ | ✅ 默认 |
👉 一句话结论:
参数 → encodeURIComponent
整条 URL → encodeURI(谨慎)
五、最常见错误示例(一定要看)
❌ 错误:对参数用 encodeURI
const keyword = "a&b=c";
const url = "https://xx.com?q=" + encodeURI(keyword);
结果:
https://xx.com?q=a&b=c
服务器收到的是:
q = "a"
b = "c"
💥 参数直接被拆了
✅ 正确写法
encodeURIComponent("a&b=c");
// a%26b%3Dc
六、escape / unescape(为什么不能用)
escape("中文"); // %u4E2D%u6587
❌ 问题:
- 不是 URL 标准
- 后端无法解析
- 已被 ECMAScript 标记为废弃
📌 结论:看到 escape,直接删
七、URLSearchParams(现代 JS 最优雅方案)
构建 URL(强烈推荐)
const params = new URLSearchParams({
keyword: "苹果 手机",
page: 1,
sort: "price_desc"
});
const url = "https://example.com/search?" + params.toString();
输出:
https://example.com/search?keyword=%E8%8B%B9%E6%9E%9C+%E6%89%8B%E6%9C%BA&page=1&sort=price_desc
✅ 自动编码
✅ 不用手拼
✅ 不容易出错
解析 URL 参数
const params = new URLSearchParams(location.search);
params.get("keyword"); // 苹果 手机
八、前后端对接的真实建议
✅ 前端
- 所有参数值 →
encodeURIComponent - 复杂参数 →
JSON.stringify + encodeURIComponent - 构建查询 →
URLSearchParams
✅ 后端
- Java:
URLDecoder.decode(str, "UTF-8") - Node:自动解码(Express)
- 永远使用 UTF-8
九、速查表(收藏级)
| 场景 | 用法 |
|---|---|
| 单个参数 | encodeURIComponent |
| 整条 URL | encodeURI |
| 解参数 | decodeURIComponent |
| 构建查询 | URLSearchParams |
| 老代码 escape | ❌ 删 |
十、一句话终极口诀
只要是“参数值”,闭眼用
encodeURIComponent
想省心,直接用URLSearchParams
如果你愿意,我可以继续帮你:
- 🔥 做一张「编码/解码对照表」图片
- 🔥 讲 Ajax / fetch / axios 中的编码细节
- 🔥 前端 + Java 后端乱码完整解决方案
你是准备用在 前端项目、爬虫,还是 前后端接口对接?