开发笔记)
URL Encoding / Decoding也叫百分号编码Percent-encoding是 Web 开发里最基础、使用频率极高但新手很容易踩坑的知识点。简单讲它用来把 URL 里不安全、非标准的字符转换成符合传输规范的 ASCII 格式保证数据正常传递。一、为什么需要 URL 编解码URL统一资源定位符用来唯一标识互联网资源按照 RFC 3986 规范合法字符分为三类未保留字符安全字符大小写英文字母、数字以及-_.~保留字符具备特殊语义:/?#[]!$()*,;百分号%专门用作转义标记实际开发里经常遇到两个问题中文、日文、Emoji 这类非 ASCII 字符直接放在 URL 里很容易出现乱码甚至请求直接失败如果参数本身包含、比如密码abcd服务端会误判成多个参数分隔符解析出来的数据完全错乱。URL 编解码就是用来解决这类问题先把原始字符转为 UTF-8 字节流再将每个字节写成% 两位十六进制数也就是%XX格式。举个常见例子汉字「中」的 UTF-8 占 3 个字节E4 B8 AD编码后就是%E4%B8%AD。二、日常开发中常用的几个场景1. GET 请求传递中文、特殊参数用百度搜索关键词时地址栏虽然展示中文但浏览器发出的真实请求是编码后的字符串。 原始地址https://www.baidu.com/s?wd火力盒子实际请求https://www.baidu.com/s?wd%E7%81%AB%E5%8A%9B%E7%9B%92%E5%AD%90如果不做编码经过代理、老旧网关转发时中文很可能被截断或者乱码。2. 通过 URL 传递 JSON 等复杂字符串页面跳转时有时需要把完整 JSON 作为参数传给下一页直接拼接会出错。 原始 JSON{name:test, age:18}错误写法?data{name:test, age:18}{、会破坏 URL 结构。 正确流程先 JSON.stringify 序列化再执行编码。 编码结果?data%7B%22name%22%3A%22test%22%2C%22age%22%3A18%7D3. 第三方接口签名校验支付、云服务对接对接微信支付、支付宝、阿里云 OSS 这类接口时为了防止参数被篡改签名流程一般要求参数按照字典升序排序所有 key、value 严格执行 URL 编码拼接字符串后再做 MD5 或 HMAC-SHA256 签名这里编码规则差一点比如空格处理不一致签名就永远无法匹配我之前对接支付接口就在这里卡过很久。4. 前端路由传参Vue / ReactHash、History 路由下如果参数自带/这类分隔符路由会错误解析成分级路径匹配失败。 例如传递文件路径C:\Users\admin\test.txt必须先编码再传参。5. 基础安全防护URL 编码不等于加密但能拦截一部分恶意构造的参数降低反射型 XSS、简单注入的风险。多数 Web 框架接收 URL 参数时会自动完成解码之后再做安全过滤。三、JS 两个编码函数的区别面试高频很多新人分不清encodeURI和encodeURIComponent实际使用场景完全不同表格特性encodeURI()encodeURIComponent()用途编码完整 URL编码 URL 内单个参数值保留字符处理不编码:/?#除字母数字、-_.!~*()外全部编码适用场景完整网址包含中文路径拼接 query 参数 value示例encodeURI(https://a.com/搜索 / 测试 ) https://a.com/%E6%90%9C%E7%B4%A2/%E6%B5%8B%E8%AF%95encodeURIComponent(a1b2) a%3D1%26b%3D2实操记住这条准则拼接查询参数一律用encodeURIComponent只有处理整条完整 URL 时才考虑encodeURI。补充其他语言常用方法Pythonurllib.parse.quote、JavaURLEncoder.encode、Gourl.QueryEscape逻辑都等价于 JS 的encodeURIComponent。四、开发里踩过的几个典型坑坑 1空格到底是还是%20URL Path路径部分空格规范编码为%20application/x-www-form-urlencoded表单、Query 参数传统规范中空格记作这里很容易出现跨语言兼容问题JS encodeURIComponent 空格输出%20Java URLEncoder 会输出前后端处理不一致解析出来的数据就带多余加号或者丢失空格。坑 2双重编码引发乱码现象前端传%E4%B8%AD后端拿到变成%25E4%25B8%25AD原因前端手动编码一次Nginx、Tomcat、Spring 这类中间件 / 框架又自动解码一次或者前端重复编码%被转成%25数据直接损坏。处理方案前后端提前约定一般前端负责编码框架自动完成解码业务代码不要再手动解码。坑 3误以为 URL 编码是加密不少新手会把密码、token 编码后直接放在 URL 传输觉得别人看不懂就是安全。 实际上编解码是公开规则任何人都能还原原始数据没有任何加密能力。敏感数据优先 HTTPS 传输如果需要加密要用 AES、RSA 这类正规加密算法加密完成后再做编码。小结URL 编解码本质是格式转换不会修改原始数据只是让字符符合 URL 的传输规范保证数据穿过网关、服务器、浏览器时不会解析异常。日常开发用好encodeURIComponent理清 UTF-8 和%XX的转换规则就能避开大部分相关问题。免费前端工具