经常使用编码方式的基本概念以及Web编程中遇到的编码问题

 


前言:php


 

  一直对ANSI、UNICODE、UTF-8,GBK等概念模糊,今天翻阅了网上相关的文章(数十篇),质量参差不齐,甚至有些做者对于其中的概念也有所混淆。因此今天就作个笔记,写个清晰简单的文章,说明个中关系。也怕本身忘记了,再回来看看。html

 


计算机篇:程序员


 

  首先要知道两个单位,一个是Bit(位),一个是Byte(字节)。前者是的信息元,后者是信息存储的基本单位,8个位组成一个字节。数据库

  ASCII码是用来对字符、数字、英文进行编码,采用10进制,且每一个字符占一个字节。而GBK的出现扩充了ASCII,使其能用两位字符表示中文汉字和日文假名。其中GB2312是专门为简体汉字编码的。GBK和GB2312只是两个例子,这种扩充ASCII使用两个字节表示一个中文字符的方法统称为ANSI标准。编程

  而UNICODE之因此后来出现,是为了统一国际标准。UNICODE编码中,每一个字符(不论中英文或符号)都是用两个字节来表示。为了解决UNICODE浪费存储空间和传输存在的缺点,基于UNICODE标准衍生出了UTF-8编码。UTF-8就是如今使用最普遍的国际编码标准。浏览器


Web篇:安全


 

  可能你们都有这样的经验,当使用FireFox浏览器时,在地址栏输入某一个带中文参数的网站时,浏览器会自动将参数转化为带%号的格式,好比将“测试”二字转化为为为%B2%E2%CA%D4。这样作是为了统一URL标准以及避免一些安全问题,于此同时,浏览器会将URL中不可控的特殊字符也转化为这种格式,俗称转化为URL格式,这样的编码方式叫作URL-encode。函数

  因为GB2312中,中文字符的表示方式为两个字节,一个字节8个位,而一位16进制数使用4个位。这样一算,一个中文字符使用4个16进制数,也就是2个2位16进制数,因此上面的例子中将“测试”转化为%B2%E2%CA%D4说明是转为GB2312格式而非UTF-8格式了。由于UTF-8中,一个中文字符用2~4个字节表示(大多数是3个字节)。这时候问题就来了,若是该网站页面设置使用UTF-8编码方式,如使用了HTML的<meta>标签:测试

<META http-equiv="content-type" content="text/html; charset=utf-8">

  或者PHP的header函数:网站

<?php
    header("content-type:text/html; charset=utf-8"); 
?>

  浏览器传输时将URL参数的中文转为GB2312格式,而解析的时候参考了了Header或者页面中的meta标签将内容按解码UTF-8格式来解码,就显示错误了。(这里header优先级高于meta,因此二者不一致的话参考header)

下面的表格说明了经常使用浏览器的预约转化方法:

  直接在地址栏输入URL

浏览器 path部分 query部分
编码种类 百分比编码 编码种类 百分比编码
IE UTF-8 GB2312
Firefox Opera UTF-8 GB2312
Chrome Safari UTF-8 UTF-8

 

 


如何解决:


 

  咱们先来假设一下这个问题出现的场景:访问者直接用浏览器访问带中文参数的网站。这样的场景虽然很少,可是终究是没法避免的,假设你的朋友在QQ上发给你一个百度的搜索结果(“中文关键字”),这样一定会出现直接访问带中文参数的URL的情景,而后结果是出现了乱码。可是经我测试,如今百度已经解决了这个问题。

  首先,客户端(浏览器)是能够更改预约转化的字符集的,但咱们应该从一个程序员的角度来解决这个问题,不是让访问者本身经过调整客户端来适应网页的编码。并且咱们得知道一点:若是在一个页面经过脚本或者超连接的形式访问这样一个带中文参数的URL的话,全部浏览器在query部分的编码统一使用当前页面的编码方式。

  要解决问题,步骤①经过refer头判断是不是直接从地址栏访问的

          ②若是知足①,则经过User-Agent判断浏览器

          ③根据上面的表格作编码转化(好比PHP的mb_convert_encoding函数

 


关于其余:


 

  网页编程中会遇到其余的编码乱码问题,其实只要解决了以前说的那个问题(最蛋疼的问题),其余的问题只要保证“文件存储编码方法-html页面编码方法-header编码方法-数据库编码方法”四者一致便可。若是同一个网站的不一样页面使用不一样的编码方式的话,那么在连接跳转的使用使用JavaScript的ESCAPE函数(举个例子)转化而不经过浏览器就好了。

  还有一个问题就是若是经过外部网站的连接访问了带中文参数的地址,且二者的编码方式不一样该如何解决?这个问题的解决方法我暂时也还没想出来,但愿Web编程有经验的同窗指教,一样的,若是文章有错误或纰漏也欢迎指出。

相关文章
相关标签/搜索