zoukankan      html  css  js  c++  java
  • 编码与乱码小结

    version 1.0

    一、【声明】
      编码三大概念:字符库;编码字符集;字符编码【转换关系】
      GB2312、GB18030:国家标准

      GBK:是继承于(兼容)GB2312的扩展方案[目前:非国家标准];GBK >> GB2312

      UTF-8的汉字数量:少于GB18030
      GBK包含全部中文字符;UTF-8则包含全世界所有国家需要用到的字符[来源:知乎]
      UTF-8与GBK:GBK包含中国全部汉字;UTF-8:有利于国际化[俗称:万国码]
      Windows系统:优先支持UTF-16;而非UTF-8


    二、【参考文档】
      0.【十分钟搞清字符集和字符编码】(https://linux.cn/article-5027-1.html) //经典文章[本文必读]
      1.【HTML <form> accept-charset 属性】(http://www.w3school.com.cn/tags/att_form_accept-charset.asp);
      2.【tomcat 的编码设置?】(https://my.oschina.net/u/224202/blog/56102)
      3.【url的三个js编码函数escape(),encodeURI(),encodeURIComponent()简介】(http://www.haorooms.com/post/js_escape_encodeURIComponent);
      4.【JavaScript(js) 前台 参数传递乱码 转码 问题--已解决! 中文字符乱码】  (http://blog.csdn.net/hurryjiang/article/details/6960298);//escape;encodeURI;encodeURIComponent

    三、【关于编码与转码的操作总结】

      Web容器端:
        1.【URIEncoding】server.xml内所在端口的connector中配置URIEncoding = "目标字符集"【默认:ISO-8859-1】
        2.【useBodyEncodingForURI】server.xml内所在端口的connector中配置:useBodyEncodingForURI="true"

      数据库:
        1.MySQL:创建数据库时候,设置采用UTF8MD5[alter database databaseName set character = utf8md5]
        2.MySQL: 修改mysql在windows\my.ini里default-character-set=utf-8

      服务器端:
        0.文件外部设置文件的编码

        1.指令
        <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> //经常使用:
        备注:此处的contentType="text/html; charset=UTF-8"比meta元素中的优先级高;故web容器优先采用此处的设置

        2.网页文件内部设置:<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

        3.request:
        [only one about set file's character]
        request.setCharacterEncoding("字符集");//经常使用

        4.对中文参数进行URL转码:java.net.URLEncoder("中文参数","GBK/UTF-8/..."); //推荐使用

        5.response:
        response.setCharacterEncoding("字符集"); //经常使用
        response.setContentType("text/html;charset=utf-8");//经常使用
        response.addHeader("content-type", "text/html;charset=utf-8");
        response.addHeader("Content-Type", "application/pdf");
        response.setHeader("content-type", "text/html;charset=utf-8");//经常使用
        response.setHeader("refresh", "5;URL=www.xxxx.com");
        response.setHeader("Pragma", "no-cache");
        response.encodeRedirectURL("字符集");//经常使用
        response.encodeRedirectUrl("不推荐使用了");
        response.encodeUrl("不推荐使用了");
        response.encodeUrl("不推荐使用了");

        6.String(s.getBytes("iso8859-1"),"客户端提交时的字符集"); //常用方式:尤其在获取客户端表单的参数乱码的时候
        Eg:new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK") //推荐使用

        7.post提交数据:处理工具org.springframework.web.filter.CharacterEncodingFilter
        <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF8</param-value>
        </init-param>
        <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
        </init-param>
        </filter>

        <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>*.html</url-pattern>
        </filter-mapping>
        <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
        </filter-mapping>

      客户端:
        0.各浏览器和系统默认采用的字符集均不同:
          chrome[UTF-8]
          IE[GB某系列]
          windows[GB2312;UTF16LE]

                 chrome应用商店中有set Character Encoding插件,可以更改网页显示的字符集【针对用户】

        1.form属性中:accept-charset="UTF-8" onsubmit="document.charset='utf-8';" //推荐使用
        2.JS脚本:
          原生JS-API:escape();
            unescape();
            ===========
            encodeURI();
            encodeURIComponent();
        3.自造编码轮子:
          var Unicode = {
            stringify : function(str) { //编码
              var res = [], len = str.length;
              for (var i = 0; i < len; ++i) {
                res[i] = ("00" + str.charCodeAt(i).toString(16)).slice(-4);
              }
              return str ? "\\u" + res.join("\\u") : "";
            },
               parse : function(str) {//解码
              str = str.replace(/\\/g, "%");
                return unescape(str);
            }
          };
      ========================
      小测试:
      function encodeAndDecode1() {
        var str1 = Unicode.stringify("我的时间123ABC"); //\u6211\u7684\u65f6\u95f4\u0031\u0032\u0033\u0041\u0042\u0043
        alert(str1);
        var str2 = Unicode.parse(str1); //我的时间123ABC
        alert(str2);
      }

      function encodeAndDecode2() {
        string = "我爱你12345才guai~";
        var str1 = escape(string); //%u6211%u7231%u4F6012345%u624Dguai%7E
        alert(str1);
        var str2 = unescape(str1); //我爱你12345才guai~
        alert(str2);
      }

    四、实际问题
    ===========================================================================
    在Eclipse中实测有效:

    实现jsp页面内的文件转码:
      方法1:
        使用page指令更改aim.jsp中的pageEncoding
        然后,在项目目录中查看aim.jsp的编码方式:已经自动更改为pageEncoding的编码方式了
      方法2:【同:更改Servlet文件编码 方式】

    更改Servlet文件编码
      先在项目目录中XXXXServlet.java文件的编码方式
      选中XXXXServlet所有代码【ctrl+a】
      撤退【ctrl+z】

    表单中文参数乱码:
      step1.form中设置属性:
        accept-charset="客户端字符集编码类型A" onsubmit="document.charset='客户端字符集编码类型A';"
      step2:服务器端:【获取数据】
        new String(request.getParameter("username").getBytes("ISO-8859-1"),"客户端字符集编码类型A"));
        //ISO-8859-1是Tomcat的默认字符集编码类型

    网页文本乱码:【问题很综合很复杂,暂时不予总结】
      【前提:数据源来自服务器,且服务器端文本正常显示】
      【假定:文件编码字符集:A;
          响应的全局字符集:B【即:CharacterEncoding】
          响应[全局下-文件]编码:C [即:ContentType("text/html;charset=响应[全局下-文件]编码")]
      】

      1.response.setContentType("text/html;charset=响应[全局下-文件]编码");
      【响应[全局下-文件]编码与文件本身的编码不一致:C!=A】
      如果C的字符集没有超出A的字库表范围,将出现乱码
      如果C的字符集超出了A的字库表范围,将出现500 服务器内部执行程序错误【严重情况】
        type Exception report

        message Servlet execution threw an exception

        description The server encountered an internal error that prevented it from fulfilling this request.

        exception

        javavax.servlet.ServletException: Servlet execution threw an exception root cause

        java.lang.Error: Unresolved compilation problems:
        The type of the expression must be an array type but it resolved to String
        Syntax error on token "Invalid Character", [ expected
        Servlet杈撳嚭 cannot be resolved to a variable
        Syntax error, insert "]" to complete ArrayAccess
        Syntax error, insert ")" to complete MethodInvocation
        Syntax error, insert ";" to complete Statement
        Syntax error on tokens, ( expected instead
        The left-hand side of an assignment must be a variable
        Syntax error, insert ")" to complete Expression
        Syntax error, insert "AssignmentOperator Expression" to complete Assignment
        Syntax error, insert ";" to complete Statement

        servlet.testServlet.doPost(testServlet.java:54)
        servlet.testServlet.doGet(testServlet.java:30)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
        note The full stack trace of the root cause is available in the Apache Tomcat/6.0.48 logs.

        response.setCharacterEncoding("响应全局编码");响应编码与文件本身的编码不一致,可能导致乱码

    赞赏-支付宝二维码
    本文作者千千寰宇
    本文链接 https://www.cnblogs.com/johnnyzen
    关于博文:评论和私信会在第一时间回复,或直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:若本文对您有帮助,可点击右下角推荐一下。您的鼓励、【赞赏】(左侧赞赏支付码)是博主技术写作的重要动力!
  • 相关阅读:
    HTTP Header 详解
    面试题----网页/应用访问慢突然变慢,如何定位问题
    PHP实现斐波那契数列
    常见的HTTP返回状态值
    通过实例理解单列索引、多列索引以及最左前缀原则
    Btree索引和Hash索引
    遍历和删除文件夹
    面试题之----禁掉cookie的session使用方案
    面试题之----写个函数来解决多线程同时读写一个文件的问题
    heredoc
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/7017857.html
Copyright © 2011-2022 走看看