关于字符编码某些事

来源:互联网 发布:linux lxde 编辑:程序博客网 时间:2024/05/18 12:37

    <!DOCTYPE html>      <html xmlns="http://www.w3.org/1999/xhtml">      <head>      <title>The Character Encoding for Form Submission</title>      <script>      function $(id) {          return document.getElementById(id)      }            function createPropertyEditor(name) {          var p = document.createElement('p')          p.appendChild(document.createTextNode(name + ' = '))          var input = document.createElement('input')          input.type = 'text'          var get = new Function('this.value = String($name); this.select()'.replace(/\$name/g, name))          get.call(input)          input.onfocus = get          input.onchange = new Function('     \              try {                           \                  $name = this.value          \              } catch(e) {                    \                  alert(e.message)            \              } finally {                     \                  this.value = String($name)  \              }                               \          '.replace(/\$name/g, name))          p.appendChild(input)          $('properties').appendChild(p)      }            var form            window.onload = function () {          form = document.forms[0]          createPropertyEditor('document.charset')          createPropertyEditor('document.defaultCharset')          createPropertyEditor('document.characterSet')          createPropertyEditor('document.inputEncoding')          createPropertyEditor('document.xmlEncoding')      //  createPropertyEditor('document.mimeType')          createPropertyEditor('form.acceptCharset')          createPropertyEditor('form.method')          createPropertyEditor('form.enctype')      //  createPropertyEditor('form.encoding')      }      </script>      </head>      <body>      <form>          <input name="_charset_" type="hidden">          <input name="test" type="text" value="简体-繁體-English">           <input type="submit">          <div id="properties"></div>      </form>      </body>      </html>  



如果你总是使用utf-8编码,则基本不用为编码问题伤脑筋。但是总有些时候,事情超出了你的掌控范围。

通常表单提交时将按照文档本身的编码进行编码。如果是一个gb2312的文档,如何按照utf-8编码提交呢?此外是否可以通知服务器,请求是按照何种方式编码的呢?

以上代码测试了浏览器为此类问题所提供的各种特性。可将上述代码保存为不同的编码,如UTF-8、GB2312、Big5等(可以加上meta httpequiv=content-type content=text/html;charset=xxx),然后进行测试(即修改document.charset和form.acceptCharset然后提交,观察URL参数的结果)。

以下是一些浏览器的测试结果(仅测试了GET请求):

Text代码  收藏代码
  1.           支持document.charset  支持form.acceptCharset  支持_charset_  
  2. IE6              Y                     N*                       Y  
  3. FF2             N                     Y                        Y  
  4. Safari3        Y                     Y                        N  
  5. Chrome1     Y                     Y                        N  
  6. Opera9       N*                    Y                        Y  


由于手头安装的浏览器有限,有兴趣的同志可帮忙测试一下IE5、IE7、IE8、FF3以及其他浏览器。


说明:

1. document.charset
可获得文档的字符编码。
也可改写,从而影响到表单提交时所采用的编码。在IE中改变charset还会影响网页的字体。
IE专有属性,Webkit引擎也实现了该属性。FF2不支持,虽然有一个document.characterSet属性,但是只读。Opera9虽然可通过charset属性读取字符编码,但是改写该属性似无意义。

2. form.acceptCharset
按照HTML4规范,FORM上的accept-charset属性(DOM中为acceptCharset)表示服务器可接受的编码列表(以空格或逗号分割多种编码)。浏览器应选取其中一种ASCII兼容的编码(具体选择哪种,各浏览器自行决定——比如chrome虽然也用webkit引擎,但是在选择编码方面似乎与safari有一些不同)作为表单数据的编码。
IE6虽然有acceptCharset属性,但是无效果。(然而据一封古老的微软工程师在unicode组织邮件列表里的邮件表明,IE5也许支持?有兴趣同志可以测试一下。)

3. _charset_

当表单包含一个name为_charset_的hidden类型input,表单提交时,_charset_的value会被设为表单数据的字符编码。

pageEncoding
     
在JSP标准的语法中,如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的charset决定,如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1。

ContentType

     ContentType属性指定了MIME类型和JSP页面回应时的字符编码方式。MIME类型的默认值是“text/html”; 字符编码方式的默认值是“ISO-8859-1”. MIME类型和字符编码方式由分号隔开

pageEncoding的内容只是用于jsp输出时的编码,不会作为header发出去的。

pageEncoding 是通知web server jsp的编码。


关于JSP页面中的pageEncoding和contentType两种属性的区别:

pageEncoding是jsp文件本身的编码

contentType的charset是指服务器发送给客户端时的内容编码

JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。

第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。

第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。

第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效

contentType的設定.

pageEncoding和contentType的预设都是 ISO8859-1. 而随便设定了其中一个, 另一个就跟着一样了(TOMCAT4.1.27是如此).但这不是绝对的, 这要看各自JSPC的处理方式. 而pageEncoding不等于contentType, 更有利亚洲区的文字CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312 不等于 contentType=utf-8)。

jsp文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可以让虚拟机得到正确的资料。

但是jsp文件不是这样,它没有这个默认转码过程,但是指定了pageEncoding就可以实现正确转码了。

举个例子:


<%@ page contentType="text/html;charset=utf-8" %>


大都会打印出乱码,因为我输入的“你好吗”是gbk的,但是服务器是否正确抓到“你好吗”不得而知。

但是如果更改为


<%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>


这样就服务器一定会是正确抓到“你好吗”了。

0 0