首页 > 其他分享 >URL中文乱码问题

URL中文乱码问题

时间:2023-06-02 21:05:19浏览次数:37  
标签:编码 中文 UTF name URL 解码 request 乱码


我们主要通过两种形式提交向服务器发送请求:URL、表单。而表单形式一般都不会出现乱码问题,乱码问题主要是在URL上面。通过前面几篇博客的介绍我们知道URL向服务器发送请求编码过程实在是实在太混乱了。不同的操作系统、不同的浏览器、不同的网页字符集,将导致完全不同的编码结果。如果程序员要把每一种结果都考虑进去,是不是太恐怖了?有没有办法,能够保证客户端只用一种编码方法向服务器发出请求?

有!这里我主要提供以下几种方法

一、javascript

使用JavaScript编码不给浏览器插手的机会,编码之后再向服务器发送请求,然后在服务器中解码。在掌握该方法的时候,我们需要料及javascript编码的三个方法:escape()、encodeURI()、encodeURIComponent()。

escape

采用SIO Latin字符集对指定的字符串进行编码。所有非ASCII字符都会被编码为%xx格式的字符串,其中xx表示该字符在字符集中所对应的16进制数字。例如,格式对应的编码为%20。它对应的解码方法为unescape()。

URL中文乱码问题_ViewUI

事实上escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如上面“我是cm”的结果为%u6211%u662Fcm,其中“我”对应的编码为6211,“是”的编码为662F,“cm”编码为cm。

注意,escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。

encodeURI

对整个URL进行编码,它采用的是UTF-8格式输出编码后的字符串。不过encodeURI除了ASCII编码外对于一些特殊的字符也不会进行编码如:! @ # $& * ( ) = : / ; ? + '。

URL中文乱码问题_字符串_02

encodeURIComponent

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。相对于encodeURI,encodeURIComponent会更加强大,它会对那些在encodeURI()中不被编码的符号(; / ? : @ & = + $ , #)统统会被编码。但是encodeURIComponent只会对URL的组成部分进行个别编码,而不用于对整个URL进行编码。对应解码函数方法decodeURIComponent。

当然我们一般都是使用encodeURI方来进行编码操作。所谓的javascript两次编码后台两次解码就是使用该方法。javascript解决该问题有一次转码、两次转码两种解决方法。

一次转码

javascript转码:



1. var url = '<s:property value="webPath" />/ShowMoblieQRCode.servlet?name=我是cm';  
2. window.location.href = encodeURI(url);



 

码后的URL:http://127.0.0.1:8080/perbank/ShowMoblieQRCode.servlet?name=%E6%88%91%E6%98%AFcm

后台处理:



  1. String name = request.getParameter("name");  
  2. System.out.println("前台传入参数:" + name);  
  3. name  = new String(name.getBytes("ISO-8859-1"),"UTF-8");  
  4. System.out.println("经过解码后参数:" + name);  



 

输出结果:

前台传入参数:??????cm 
经过解码后参数:我是cm

二次转码

javascript


1. var url = '<s:property value="webPath" />/ShowMoblieQRCode.servlet?name=我是cm';  
2. window.location.href = encodeURI(encodeURI(url));


 

码后的url:http://127.0.0.1:8080/perbank/ShowMoblieQRCode.servlet?name=%25E6%2588%2591%25E6%2598%25AFcm

后台处理:



    1. String name = request.getParameter("name");  
    2. System.out.println("前台传入参数:" + name);  
    3. name  = URLDecoder.decode(name,"UTF-8");  
    4. System.out.println("经过解码后参数:" + name);



     

    输出结果:

    前台传入参数:E68891E698AFcm 

    经过解码后参数:我是cm

     

    filter

    使用过滤器,过滤器LZ提供两种,第一种设置编码,第二种直接在过滤器中进行解码操作。

    过滤器1

    该过滤器是直接设置request的编码格式的。


    1. public class CharacterEncoding implements Filter {  
    2.   
    3. private FilterConfig config ;  
    4. null;  
    5.       
    6. public void destroy() {  
    7. null;  
    8.     }  
    9.   
    10. public void doFilter(ServletRequest request, ServletResponse response,  
    11. throws IOException, ServletException {  
    12.         request.setCharacterEncoding(encoding);  
    13.         chain.doFilter(request, response);  
    14.     }  
    15.   
    16. public void init(FilterConfig config) throws ServletException {  
    17. this.config = config;  
    18. //获取配置参数  
    19. "encoding");  
    20. if(str!=null){  
    21.             encoding = str;  
    22.         }  
    23.     }  
    24.   
    25. }


     

    配置:



      1. <!-- 中文过滤器的配置 -->  
      2. <filter>  
      3. <filter-name>chineseEncoding</filter-name>  
      4. <filter-class>com.test.filter.CharacterEncoding</filter-class>  
      5.           
      6. <init-param>  
      7. <param-name>encoding</param-name>  
      8. <param-value>utf-8</param-value>  
      9. </init-param>  
      10. </filter>  
      11.       
      12. <filter-mapping>  
      13. <filter-name>chineseEncoding</filter-name>  
      14. <url-pattern>/*</url-pattern>  
      15. </filter-mapping>  
      16.


       

      过滤器2

      该过滤器在处理方法中将参数直接进行解码操作,然后将解码后的参数重新设置到request的attribute中。



        1. public class CharacterEncoding implements Filter {  
        2. protected FilterConfig filterConfig ;  
        3. null;  
        4.       
        5. public void destroy() {  
        6. this.filterConfig = null;  
        7.     }  
        8.   
        9. /**
        10.      * 初始化
        11.      */  
        12. public void init(FilterConfig filterConfig) {  
        13. this.filterConfig = filterConfig;  
        14.     }  
        15.   
        16. /**
        17.      * 将 inStr 转为 UTF-8 的编码形式
        18.      * 
        19.      * @param inStr 输入字符串
        20.      * @return UTF - 8 的编码形式的字符串
        21.      * @throws UnsupportedEncodingException
        22.      */  
        23. private String toUTF(String inStr) throws UnsupportedEncodingException {  
        24. "";  
        25. if (inStr != null) {  
        26. new String(inStr.getBytes("iso-8859-1"), "UTF-8");  
        27.         }  
        28. return outStr;  
        29.     }  
        30.   
        31. /**
        32.      * 中文乱码过滤处理
        33.      */  
        34. public void doFilter(ServletRequest servletRequest,  
        35. throws IOException,  
        36.             ServletException {  
        37.         HttpServletRequest request = (HttpServletRequest) servletRequest;  
        38.         HttpServletResponse response = (HttpServletResponse) servletResponse;  
        39.   
        40. // 获得请求的方式 (1.post or 2.get), 根据不同请求方式进行不同处理  
        41.         String method = request.getMethod();  
        42. // 1. 以 post 方式提交的请求 , 直接设置编码为 UTF-8  
        43. if (method.equalsIgnoreCase("post")) {  
        44. try {  
        45. "UTF-8");  
        46. catch (UnsupportedEncodingException e) {  
        47.                 e.printStackTrace();  
        48.             }  
        49.         }  
        50. // 2. 以 get 方式提交的请求  
        51. else {  
        52. // 取出客户提交的参数集  
        53.             Enumeration<String> paramNames = request.getParameterNames();  
        54. // 遍历参数集取出每个参数的名称及值  
        55. while (paramNames.hasMoreElements()) {  
        56. // 取出参数名称  
        57. // 根据参数名称取出其值  
        58. // 如果参数值集不为空  
        59. if (values != null) {  
        60. // 遍历参数值集  
        61. for (int i = 0; i < values.length; i++) {  
        62. try {  
        63. // 回圈依次将每个值调用 toUTF(values[i]) 方法转换参数值的字元编码  
        64.                             String vlustr = toUTF(values[i]);  
        65.                             values[i] = vlustr;  
        66. catch (UnsupportedEncodingException e) {  
        67.                             e.printStackTrace();  
        68.                         }  
        69.                     }  
        70. // 将该值以属性的形式藏在 request  
        71.                     request.setAttribute(name, values);  
        72.                 }  
        73.             }  
        74.   
        75.         }  
        76. // 设置响应方式和支持中文的字元集  
        77. "text/html;charset=UTF-8");  
        78.   
        79. // 继续执行下一个 filter, 无一下个 filter 则执行请求  
        80.         chain.doFilter(request, response);  
        81.     }  
        82. }



         

        配置:



          1. <!-- 中文过滤器的配置 -->  
          2. <filter>  
          3. <filter-name>chineseEncoding</filter-name>  
          4. <filter-class>com.test.filter.CharacterEncoding</filter-class>  
          5. </filter>  
          6.       
          7. <filter-mapping>  
          8. <filter-name>chineseEncoding</filter-name>  
          9. <url-pattern>/*</url-pattern>  
          10. </filter-mapping>



           

          其他

          1、设置pageEncoding、contentType


          1. <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>

           

          2、设置tomcat的URIEncoding

          在默认情况下,tomcat服务器使用的是ISO-8859-1编码格式来编码的,URIEncoding参数对get请求的URL进行编码,所以我们只需要在tomcat的server.xml文件的<Connector>标签中加上URIEncoding="utf-8"即可。


          标签:编码,中文,UTF,name,URL,解码,request,乱码
          From: https://blog.51cto.com/u_16131764/6404903

          相关文章

          • 记录--让URL地址都变成了"ooooooooo"
            这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助发现一个很有创意的小工具网站,如封面图所示功能很简单,就是将一个URL地址转换为都是ooooooooo的样子,通过转换后的地址访问可以转换回到原始地址,简单流程如下图所示。转换的逻辑有点像短链平台一样,只不过这个是将......
          • c++ libcurl获取http header信息
            boolHttpDownloader::GetReceiveHeaderInfo(conststd::string&strUrl,std::map<std::string,std::string>&mapHeaderKeyValue){boolbRet=false;if(strUrl.empty()){returnbRet;}else{CURL*handl......
          • How to Find Django ImageField URL
            Thissetupisworkingforme,maybeitwillhelpyou.ItisforlatestversionofDjango.ManyanswersinOSareforolderDjangoversions.URLS:fromdjango.conf.urls.staticimportstaticfromdjango.confimportsettingsurlpatterns=[#url]+static(s......
          • 基于shiro+jwt的真正rest url权限管理,前后端分离
            bootshiro&usthebootshiro是基于springboot+shiro+jwt的真正restfulURL资源无状态认证权限管理系统的后端usthe是restfulURL资源无状态认证权限管理系统的前端,基于angular+typeScript+adminLte区别于一般,提供页面可配置式的,动态的restfulapi安全管理支持数据传输动态......
          • CAN 总线 TJA1050/DP1050 引脚定义以及中文资料
            1简述DP1050是一款应用于CAN协议控制器和物理总线之间的接口芯片,可应用于卡车、公交、小汽车、工业控制等领域,速率可达到1Mbps,具有在总线与CAN协议控制器之间进行差分信号传输的能力,完全兼容“ISO11898”标准。DP1050芯片特点-完全兼容“ISO11898”标准;-内置过温......
          • OPEN AI接入MidJourney 画图支持GPT4中文智能优化效果惊艳
            OPENAI平台开放免费AI聚合服务平台,提供应用程序一键接入AI画图,对话的能力。目前已经支持GPT3和GPT4普通对话和流式对话。支持GPT画图和MidJourney画图。后续还会接入更多功能在线接入案例演示体验这里主要展示一下MJ的强大的画图功能关于平台平台发展版本来龙......
          • 界面组件DevExpress WPF中文指南 - 如何应用系统强调色及主题切换
            在最新版本的MicrosoftOffice产品中,用户可以根据系统设置选择主题,当使用这个主题时,Office将采用Windows强调色和应用模式(亮/暗)设置,并将它们应用到Office本身。如果用户在操作系统中更改了强调色或应用模式,Office会检测到此更改并自动更新应用程序的外观。使用DevExpressWPF ......
          • Web安全测试—URL中的大小写敏感
            URL中某些部分是大小写敏感的(意思是大写和小写字母表示不同内容),其他部分则对大小写不敏感。我们来简单的了解下协议标识符(HTTP或HTTPS)是大小写不敏感的。我们输入HTTP、http、hTPt,都是可以的。用户ID和密码一般情况下是敏感的,除非所使用的服务器软件不在意大小写。......
          • WebStorm 2023(Web前端开发工具) v2023.1.2中文mac版
            WebStorm2022mac版是一款基于WebSocket的Web应用程序编程工具,旨在通过Web应用程序的代码将HTML和CSS文本从浏览器返回到服务器。WebStorm采用MVC架构,其中每个模块都在其内部运行。WebStorm适用于JavaScript和相关技术的集成开发环境。类似于其他JetBrainsIDE,它也会......
          • Template execution failed ReferenceError BASE_URL is not defined
            错误VueTemplateexecutionfailed:ReferenceError:BASE_URLisnotdefinedReferenceError:BASE_URLisnotdefined解决替换index.html替换前<linkrel="icon"href="<%=BASE_URL%>favicon.ico">替换后<linkrel="icon"......