zoukankan      html  css  js  c++  java
  • url中拼接中文参数,后台接收为乱码的问题

    遇到在URL中拼接中文的参数,后台拿到的数据为乱码的问题,这里来说一下问题出现的原因与解决方法。

    大家比较关心的应该是解决的方法,因此先说解决方法。

    解决方法

    解决的方法是在客户端对这个中文参数进行编码,然后服务端再进行响应的解码就行了。

    客户端编码(JavaScript)

    var url = "contract!select.action?chineseParam=" + encodeURI(encodeURI("我是中文参数"));

    注意:编码的时候需要使用两次encodeURI()方法,写一个的后台输出是???号,写两个的后台输出则是%4d%5a这种,原因后面再说。

    服务端解码(Java)

    String chineseParam = java.net.URLDecoder.decode(chineseParam, "UTF-8");

    这样就能实现中文参数的前后端传递了。

    另外要注意的是,这种解决方法只有在拼接URL参数的场景下有效,如果是将参数传递放在请求体中,比如AJAX中的data,是不需要对中文参数进行手动编码和解码操作的,只需要保证前后端的编码配置一致即可。

    乱码的产生原因与乱码的简单解析

    聪明的你可能会发现,大多数的中文乱码是通过GET方式产生的。这是因为GET方式有自动解码的操作,相当于执行代码:

    URLDecoder.decode("%E6%B1%89%E5%AD%97", "编码方式");

    这是产生乱码的根本原因。

    Tomcat中乱码产生的原因以及解决方法

    在Tomcat的配置文件server.xml中,如果不配置解码方式的话,就会按照默认的ISO-8859-1编码进行解码,具体可以参照Tomcat的文档。

    URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

    这也就意味着服务端会默认执行这样的代码:

    URLDecoder.decode("%E6%B1%89%E5%AD%97", "ISO-8859-1");

    因为浏览器通常是使用的UTF-8编码,如果使用ISO解码的话,就会出现乱码。其中,【%E6%B1%89%E5%AD%97】是前端encodeURI("汉字")  的结果,此函数使用UTF-8编码。

    所以,Tomcat应该在配置文件中增加【URIEncoding="UTF-8"】的配置,避免乱码的问题产生。

    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />

    乱码时的问号?

    前端处理汉字时用的encodeURI是按照UTF-8方式进行编码,而此种编码方式是一个汉字占3字节。而通过request取到的参数默认是通过ISO-8859-1的方式进行解码的,在编码表中找不到对应的字符就显示【?】了,并且是3倍于汉字的个数,即3个【?】号代表一个汉字。

    为什么通过两次encodeURI可以解决乱码问题

    回到最上面的解决方法。

    将【汉字】通过encodeURI或者encodeURIComponent编码一次,会得到字符串【%E6%B1%89%E5%AD%97】(6个字节),此字符串使用UTF-8编码的,如果此时用ISO-8859-1解码,因为在ISO-8859-1的编码表中找不到【E6】等字段对应的字符,所以是6个问号。

    而第二次编码则相当于对非中文字符【%E6%B1%89%E5%AD%97】进行编码,得到的是字符串【%25E6%25B1%2589%25E5%25AD%2597】,此时服务端无论采用哪种解码方式,都将得到【%E6%B1%89%E5%AD%97】字符,就可以被正确解析了。这样,最后再通过UTF-8解码该字符,就可以得到【汉字】了,相当于执行了以下代码:

    URLDecoder.decode("%E6%B1%89%E5%AD%97", "UTF-8");

    所以通过两次encodeURI就可以解决大部分的乱码问题。

    "人生最遗憾的,莫过于轻易地放弃了不该放弃的,却固执地坚持了不该坚持的。"

  • 相关阅读:
    Linux网络编程--socket
    UDP学习总结
    TCP协议学习总结
    DNS协议总结
    DHCP协议总结
    ARP协议总结
    二层协议--MPLS协议总结
    二层协议--LLDP协议总结
    二层协议--LACP协议总结
    二层协议--STP协议总结
  • 原文地址:https://www.cnblogs.com/yanggb/p/11121566.html
Copyright © 2011-2022 走看看