当前位置:首页 > 热点

url传参中文乱码

我用Python写了个爬虫,传参中抓某网站的文乱数据,结果发现URL里带的传参中中文参数传到服务器端全变成了问号。排查了半天,文乱最后发现是传参中没对中文做URL编码。

URL传参这件事,文乱说白了就是传参中浏览器和服务器之间约定的一种“地址书写规则”。规则里只允许ASCII字符集里的文乱字母、数字和少数符号直接出现。传参中中文属于非ASCII字符,文乱直接塞进URL里,传参中服务器那边解析出来自然就是文乱乱码或者问号。

我见过最典型的传参中场景是搜索功能。用户在搜索框输入“北京天气”,文乱前端把参数拼到URL上,传参中如果没编码,后端拿到的可能就是“æ°å¤©”这种鬼东西。有一次我调试一个老项目,看到日志里全是这种乱码,第一反应是数据库编码问题,折腾半天才发现是URL传参环节根本没做处理。

解决办法其实很粗暴——用encodeURIComponent()把中文转成%开头的一串十六进制编码。比如“北京”转完是%E5%8C%97%E4%BA%AC,服务器收到后再解码还原。这套机制叫百分号编码,RFC 3986标准里写得清清楚楚。

但这里有个坑。很多人分不清encodeURI()和encodeURIComponent()的区别。前者不会编码:/?#[]@这些URL结构符,后者全给你转掉。我之前就见过同事用encodeURI()编码参数,结果参数值里带个&符号,直接把URL截断了,参数对不上号。

后端那边也得配合。Java里用URLDecoder.decode(),Python用urllib.parse.unquote(),PHP直接urldecode()。光前端编码不够,后端不解码照样乱码。更麻烦的是有些框架自动帮你解了,有些没解,你得看框架文档确认。

还有一种情况容易被忽略——GET和POST的编码方式不一样。GET参数在URL里,必须百分号编码。POST如果走application/x-www-form-urlencoded格式,body里的中文也会被编码,但编码规则和URL里略有差异。我自己写接口时习惯统一用UTF-8,前端和后端都约定好字符集,能省掉一大半乱码问题。

说到字符集,顺便提一嘴。就算你编码了,服务器解码时用的字符集不对,照样乱码。比如你前端用UTF-8编码,后端却用GBK解码,结果就是一堆乱码符号。这个问题在老旧系统里特别常见,尤其是那些还停留在GB2312时代的内部系统。

最后说个实际案例。上个月帮朋友调一个微信小程序接口,前端传中文地址给后端,后端收到的永远是???。查了半天,发现是后端网关层配置了request.setCharacterEncoding("ISO-8859-1"),这玩意儿根本不支持中文。改成UTF-8后问题立刻消失。有时候乱码根本不是URL编码的事,而是服务器容器默认字符集在作怪。

写代码这么多年,URL乱码问题几乎每个项目都能碰到。记住一个原则:前端编码,后端解码,两边统一UTF-8,基本能解决90%的问题。剩下的10%,多半是某个中间环节偷偷改了字符集——那种问题排查起来最费时间,我一般直接抓包看原始请求,一抓一个准。

分享到: