首页 > php教程 > php手册 > 解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

WBOY
发布: 2016-06-06 19:58:44
原创
1233 人浏览过

在Windows上编写html或php代码的时候,本地编辑器设置的文件编码式是utf-8保存,但是浏览器打开页面的时候经常出现乱码,而且浏览器自动检测到的页面编码为GBK式,这时候我就开始纳闷了? 为什么会这样了,我用 记事本打开编写过的文件,然后另存为,在编码

            在Windows上编写html或php代码的时候,本地编辑器设置的文件编码格式是utf-8保存,但是浏览器打开页面的时候经常出现乱码,而且浏览器自动检测到的页面编码为GBK格式,这时候我就开始纳闷了?

       为什么会这样了,我用记事本打开编写过的文件,然后另存为,在编码方式中选择utf-8,然后保存,再到浏览器中打开,发现正常显示了这时候我就开始思考,为什么记事本设置编码格式utf-8就能生效而编辑器不行了。经过分析发现,在这些编辑器中设置utf-8无BOM,浏览器都会出现乱码而且检测页面编码为GBK,设置为UTF-8含BOM的时候,页面就能正常显示。

       UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。
UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。
在其他非windows操作系统上UTF-8 的网页代码不应使用 BOM,否则常常会出错。

       关于UTF-8 和BOM的分析

      BOM是啥。这个就不解释了,Wikipedia上很详细。http://en.wikipedia.org/wiki/Byte_order_mark
        在网页上使用BOM是个错误。BOM设计出来不是用来支持HTML和XML的。要识别文本编码,HTML有charset属性,XML有encoding属性,没必要拉BOM撑场面。虽然理论上BOM可以用来识别UTF-16编码的HTML页面,但实际工程上很少有人这么干。毕竟UTF-16这种编码连ASCII都双字节,实在不适用于做网页。
       其实说BOM是个坏习惯也不尽然。BOM也是Unicode标准的一部分,有它特定的适用范围。通常BOM是用来标示Unicode纯文本字节流的,用来提供一种方便的方法让文本处理程序识别读入的.txt文件是哪个Unicode编码(UTF-8,UTF-16BE,UTF-16LE)。Windows相对对BOM处理比较好,是因为Windows把Unicode识别代码集成进了API里,主要是CreateFile()。打开文本文件时它会自动识别并剔除BOM。Windows用这个有历史原因,因为它最初脱胎于多代码页的环境。而引入Unicode时Windows的设计者又希望能在用户不注意的情况下同时兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助这种小trick了。相比之下,Linux这样的系统在多locale的环境中浸染的时间比较短,再加上社区本身也有足够的动力轻装前进(吐槽:微软对兼容性的要求确实是到了非常偏执的地步,任何一点破坏兼容性的做法都不允许,以至于很多时候是自己绑住自己的双手),所以干脆一步到位进入UTF-8。当然中间其实有一段过渡期,比如从最初全UTF-8的GTK+2.0发布到基本上所有GTK开发者都弃用多locale的GTK+1.2,我印象中至少经历了三到四年。
       BOM不受欢迎主要是在UNIX环境下,因为很多UNIX程序不鸟BOM。主要问题出在UNIX那个所有脚本语言通行的首行#!标示,这东西依赖于shell解析,而很多shell出于兼容的考虑不检测BOM,所以加进BOM时shell会把它解释为某个普通字符输入导致破坏#!标示,这就麻烦了。其实很多现代脚本语言,比如Python,其解释器本身都是能处理BOM的,但是shell卡在这里,没办法,只能躺着也中枪。说起来这也不能怪shell,因为BOM本身违反了一个UNIX设计的常见原则,就是文档中存在的数据必须可见。BOM不能作为可见字符被文本编辑器编辑,就这一条很多UNIX开发者就不满意。
       顺便说一句,即使脚本语言能处理BOM,随处使用BOM也不是推荐的办法。各个脚本语言对Unicode的处理都有自己的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM简单而且可靠。另一个好消息是,即使是必须在Windows和UNIX之间切换的朋友也不会悲催。幸亏在UNIX环境下我们还有VIM这种神器,即使遇到BOM挡道,我们也可以通过 set nobomb; set fileencoding=utf8; w 三条命令解决问题。
最后回头想想,似乎也真就只有Windows坚持用BOM了。

      字符编码相信是每个程序员的噩梦,只要是有中文的地方,总是会遇到各种编码的问题,并且这种问题还非常难缠,尤其在linux上,因为上面很多软件都是针对英语国家开发的,是不会考虑其他语种编码问题。在遇到编码的无数大坑之后,我决定仔细研究下编码问题,因为这就像一道坎一直横在你面前,每次到这里你都会跌到,每次爬起来之后,你都若无其事,这样的人被称作战士,真正的战士。可惜是个力量战士,做为新时代的智力战士,当然不能在那跌到然后又在这继续跌到。
       文件的存储方式:
文件都有自己的存储格式,比如最常见的txt,cpp,h,c,xml ,png, rmvb各种格式,还有自定义格式。这些文件不论是什么格式,都是存储在计算机硬盘里的2进制格存储,对应不同文件格式,有不同的软件解析。这篇文章不谈文件是如何存储的,只谈文件是如何解析的。
       文本文件解析:
       文本文件对应于人类可以阅读的文本,如何从2进制转换为文本文件呢?起初由于计算机在美国发明,自然大家考虑的是英语如何表示,英语字母总共26个,加上特殊字符,128个字符,7位既一个byte即可表示出来。这个就是大家所熟知的ascill编码。对应关系很简单,一个字符对应一一个byte。
       但很快发现,其他非英语国家的文字远远超过ascill码,这时候大家当然想统一一下,不同国家出了自己不同的编码方式,中国的gb2312就是自己做出来的编码方式,这样下去每个国家都有自己的编码方式,来回转换太麻烦了。这时候出现了新的编码方式,unicode编码方式,想将编码统一,所以规定了每个字符对应的unicode码。
1、很多文件都是ascii编码,如果用unicode 太浪费。
2、没有标志位说明该几个字节来解析为一个符号。
这时候拯救世界的utf出现了,utf是unicode的一种实现,只不过更聪明了。utf16是占用两字节,或者四字节,utf32是占用四字节。utf8是很聪明的一种表示方式。
1、对于单字节符号,字节第一位为0,后面7位表示字节编码。
2、对于n字节符号,第一字节的前n位都设为1,第n+1位为0,其余位位编码位置。
对于不同的编码,在文本的最前方有不同的标志,unicode 通常有两位来表示分别是ff fe, 或者feff, fffe表示litte-endian 编码feff表示big-endian编码。utf8是efbbbf来开头的。可以看出来utf-8是自解释的,所以不用带这个标志文件,大多数程序是可以识别的。但有些程序不能识别这个标志,比如php就会直接把这个标志当文本解析,不会忽略。相信很多遇到php输出文本解析乱码或者解析错误的同学都遇到这样的问题。
最后说说如何去掉或者加上bom,如果有vim那最好不过了,去掉命令:
set encoding=utf-8
set nobomb
添加命令:
set encoding=utf-8
set bomb

Windows系统保存的都是有BOM的,所以你可以看到,用记事本保存一个UTF-8的txt,其实是有BOM的,这一点需要注意。另外不同的文本编辑器对于有无BOM的称呼也略有不同,比如EditPlus,有BOM的称为UTF-8+,无BOM的称为UTF-8,而Notepad++中,有BOM的被称为标准UTF-8,而无BOM则被称为UTF-8无BOM。

<span><span>DOCTYPE html</span><span>></span>
<span><span>html</span><span>></span>
<span><span>head</span><span>></span>
<pre class="brush:php;toolbar:false">meta
登录后复制
登录后复制
http-equiv="Content-Type" content="text/html;charset=utf-8"> title>HTML5的标题title>
<span></span><span>head</span><span>></span>
登录后复制
登录后复制
<span><span>body</span><span>></span><span><span>p</span><span>></span>HTML5的内容!Hello<span></span><span>p</span><span>></span></span></span>
登录后复制
<span></span><span>body</span><span>></span>
登录后复制
登录后复制
<span></span><span>html</span><span>></span>
登录后复制
登录后复制

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

用记事本写的,保存后在网页上运行竟然出现了乱码。换成GB2312能正确显示中文。

<span><span>DOCTYPE html</span><span>></span>
<span><span>html</span><span>></span>
<span><span>head</span><span>></span>
<pre class="brush:php;toolbar:false">meta
登录后复制
登录后复制
http-equiv="Content-Type" content="text/html;charset=gb2312"> title>HTML5的标题title>
<span></span><span>head</span><span>></span>
登录后复制
登录后复制
<span><span>body</span><span>></span></span>
登录后复制
<span><span>p</span><span>></span>HTML5的内容!Hello<span></span><span>p</span><span>></span></span>
登录后复制
<span></span><span>body</span><span>></span>
登录后复制
登录后复制
<span></span><span>html</span><span>></span>
登录后复制
登录后复制

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

但是毕竟标准不一样。还是要用Utf-8。最后发现代码没有一点问题,问题就出记事本身上  只是告诉浏览器要用utf-8来解释,而文档的编码,是在你保存时的选择决定的。如果保存ANSI 然后用utf-8解释,肯定是乱码。记事本的话,默认保存的文件格式是ANSI。所以在保存的时候要修改为uif-8。记事本编写时一定要注意了。


用EditPlus写html页面的时候,发现设置为UTF-8的时候仍然出现了乱码

然想起页面
保存时候的编码问题,在保存页面的时候EditPlus默认的是ANSI的编码方式,而不是UTF-8。所以在保存页面的时候注意选择编码方式为UTF-8即可。(注意浏览器编码必须设置为自动选择模式
如果要修改EditPlus默认的编码方式,可以在tools---configure user tools,配置为Default encoding为UTF-8即可。(说明在Editplus上设置了文档保存编码UTF-8还是出现乱码,Editplus必须设置为UTF-8+BOM 才行,但是记事本保存设置UTF-8显示没问题
如下图配置:

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

解决浏览器抛出乱码,(HTML、PHP等的乱码问题)

原因:
在保存文件到计算机硬盘的时候,文件保存的内容已经和本机采用的编码相关,采用了计算机上有的某种编码方式来存储。
在简体中文系统中ANSI代表的就是GB2312,繁体似乎是GBK,而在日文操作系统下,ANSI 编码代表 JIS 编码。
使用 2 个字节来代表一个字符的各种语言字体编码方式,称为 ANSI 编码
所以如果保存时候用的是ANSI, Html页面中的meta定义的是
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门推荐
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板