URL传参数导致乱码
今天在通过jsp给后端传参过程中,发现后台接收的是乱码。花了两个小时,终于解决了,现在记录一下。
背景
现在有一个jsp页面,里面主要的内容是表格,其中表格中的每一行最后一列是操作部分,点击可以对该行进行修改或删除。
如上图,点击"修改"会将左边的参数传给后台。"配电主类型"和"配电副类型"两列看着是文字,实际上传的是数字;参数类型这一项不参与上传;"参数编码"和"参数名称"两项是文字,除此之外,还有一个uuid会传给后台。如下图所示:
在浏览器的地址栏上显示了我所上传的内容:
paraId就是前面提到的uuid;devMainType和devSubType对应配电主类型和配电副类型;paraCode和paraName两项是本文关注的重点,即前面提到的参数编码和参数名称。
问题
在提交了URL之后,会把这些参数传给后台代码,后台代码将转到另一个前端jsp页面,将传的参数显示出来。在这里,后台代码只负责中转,并未对上传参数作处理。但是在显示页面中却出了问题:
(因为其它几项是正常的,就没有截图)本来是中文的参数编码和参数名称都已经乱掉了。
思路
回想整个过程,前端jsp(代号A)获取表格某行中的数据,然后将这些数据传给浏览器(代号B),B将参数传给后台C。
- 首先,保证A到B,参数没有乱。
通过对参数加console.log(),发现传的是中文,check.
- 其次,检查C接收的是还是乱码。如果不是乱码,说明是C的原因导致最后显示有问题;如果已经是乱码,说明是B到C的过程出现了问题。
对后台加断点,发现在接收的时候,就已经是乱码了。
结论:B应该背锅。
检查浏览器
重新看一下A传数据B的时候发生了什么。打开Chrome Developer Tool
把URL部分放大:
可以发现,paraCode和paraName两项已经变成了%E6%B5%8B等字样。。。。
上面这张图的第一行右边还有"view parsed",点开看一下:
没错,解析出来的确实是我传的。然而被浏览器编码成了这样子:
现在已经可以肯定,浏览器对我URL里面的中文做了某种格式的编码,就变成了%E6%B5...这个样子。那是哪种格式的编码呢?通过站长工具一个一个的试,最后发现是URL编码。
解决
既然浏览器会对中文编码,那传给浏览器时不要包含中文不就好了嘛。但A取到的表格中的数据就是中文怎么办呢?可以在A里就对这些中文进行编码,编码后的结果就是%E6%B5%8B%E8%AF%95了,这时候浏览器就不会再对它加编码了。
步骤
在A中,对paraCode和paraName加两次encodeURI()
在C中,对接收到的参数加一次decode
然后重新看一下最终的显示页面
这两个中文终于能正常显示了:)
疑问1
为什么要A中是两次编码,而C中只有一次解码呢?这是因为tomcat容器已经默认解了一次码。
那又要问了,既然容器默认已经有解码了,那在A中加一次编码,C中不解码可不可以呢?
可能可以,可能不可以。因为容器解码时使用的编码方式是容器的默认编码方式,可能是UTF-8,可能是GBK,也有可能是其它乱七八糟的编码方式。你不能保证跟你的编码方式相同。所以这种方式可能会出现乱码。
如果觉得两次编码的方式太烦了,而一定要使用这种一次编码的方式也是可以的。这里就需要修改容器的默认编码方式,让它与你的编码方式相同。比如修改成UTF-8。怎么修改呢?在tomcat安装目录下conf目录下的server.xml:
把这一行变成
疑问2
细心的朋友可能发现了,浏览器对中文编码之后,向C传的明明是%E6%B5%8B%E8%AF%95这种形式的,为什么C接收到的却是&æ&mirco...这样的html转义字符了呢?好吧,我也不清楚。。。
参考资料:
[1] 关于URL编码 (http://www.ruanyifeng.com/blog/2010/02/url_encoding.html)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义