zoukankan      html  css  js  c++  java
  • [轉]Unicode签名BOM引发的事故

    from http://www.xij.cn/blog/?p=119

    Unicode签名BOM引发的事故

    做前端开发的同学大概都遇到过这样的问题,IE下平白无故的空出一行,而Firefox下是正常的,你怎么查也查不出是什么原因导致的,因为根本看不出哪里有问题。可能你这里用了包含(include)文件,通常header和footer会这么做。打开被包含文件发现页面属性中“包括Unicode签名BOM”这一项是勾选的,那么我告诉你就是这个BOM引发的事故。

    unicode-bom

    今天我在写一个JS脚本的时候又出现了BOM事故。
    我在页面中插入一个外部JS,然后里面有这样一句话$.getJSON(“/my/newmsg”,function(data){alert(data);});其它浏览器都能正常的弹出内容,唯独IE下没动静,我郁闷了近一个小时,我怀疑这句话写错了怀疑JSON数据格式错了怀疑我人品有问题…
    后来我怀疑编码不对,于是就看到了可恶的BOM打了勾,把它一去掉神迹就从乌云底下冒了出来。
    虽然我懒惰很少更新博客,但不得不上来记录一下这个事,因为真是太意外了,JS也会因为BOM引发事故 – -|

    Unicode规范中有一个BOM的概念。
    BOM是Byte Order Mark的简写,就是字节序标记,这个东西在普通文本编辑器下是看不到的,可以说它是文件头吗?在二进制编辑器下才可以看到?可能是这样。
    在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。
    UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。Windows就是使用BOM来标记文本文件的编码方式的。

    from http://liangchuanfei011.blog.163.com/blog/static/3184295820076106442981/

    Warning Cannot send session cookie - headers already sent...问题的解决(PHP的UTF-8 BOM引起的问题)

    习惯了用edit plus进行php编程,所以有时会出现一些不为人知的错误,很麻烦;
    近日,在开发项目时,某些页面总是出现以下问题:

    Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at E:\web\Apache2\htdocs\index.php:1) in E:\web\Apache2\htdocs\functions\sessions.php on line 67

    Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at E:\web\Apache2\htdocs\index.php:1) in E:\web\Apache2\htdocs\functions\sessions.php on line 67
    经过详细搜索,得到以下原因:
     我的edit plus中设置了默认的编码为utf-8,且UTF_8签名为:总是添加签名;
    于是尝试以下操作:
    在edit plus 的工具->参数->文件->UTF_8签名一项中,更改选项"总是添加签名"为"总是移除签名",然后打开index.php文件,并重新另存为,重新运行脚本,终于可以正常了;

    另外,在网上找到了两篇比较有参考价值的文章,希望有人碰到此种情况时可以完美解决!


    一个UTF-8 BOM引起的PHP的诡异问题2007-06-30 14:29一、

    //---a.php
    <?php
    header("Content-Type: image/BMP");
    session_start();
    ................
    ?>
    将a.php保存为utf-8格式,结果用浏览器访问这个php文件,就会出现如下错误:
    Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started

    at ×××.php:1) in ×××on line 2

    这个问题很常见,多数是因为在session_start之前有输出了!对于老鸟来说,这个错误基本上不会发生,但是如果你是用DW或是editplus等编

    辑器写代码的,连高手也有可能发生这个错误!

    如上面的提示:在第×××文件的第1行,×××文件的第2行,随你看,这两处是不会有任何输出语句的,很奇怪还是会出错,为什么呢
    原来:

    Unicode 签名 (BOM) 可在文档中包括字节顺序标记 (BOM)。BOM 是位于文本文件开头的 2 到 4 个字节,可将文件标识为 Unicode,如果是这

    样,还标识后面字节的字节顺序。由于 UTF-8 没有字节顺序,因此可以选择添加 UTF-8 BOM。对于 UTF-16 和 UTF-32,这是必需的。
    看见没有!如果选了这个选项,就会在页面的最前面输出2到4个字节!

    而 session_start() 要求之前没有任何输出给客户端浏览器


    二、

    另外还有一个地方可能会出错,例如:
    /--a.php--
    ?>
    空行
    空行

    如果你包含a.php之后再来也会有这个问题,通常的建议是经常被包含的文件末尾不要有?>

    又如:
    在调用Session_Start()之前不能有任何输出.例如下面是错
    误的.
    ==========================================
    1行
    2行<?PHP
    3行 Session_Start();//之前在第一行已经有输出
    4行.....
    5行?>
    ==========================================

    已经经过试验,事实确实是如此诡异。
    三、

    session_start()
    set_cookie()
    header()
    前面都加上@应该可以抑制这个警告。


    四、

    在editplus编辑器中,如果先把utf-8的a.php文件转换为gb2312或是其他,然后再转换为utf-8这样就可以成功访问了,也就是说文件开头的

    BOM被去掉了,这时候的UTF-8 是无BOM类型的了


    PHP-关于utf-8编码问题引起的session_start()错误
     
    2007-02-15 14:55:01
     
    大中小
    采用默认的gb2312编码时,兼容Ansi编码,文件头部无任何附加信息,此时session_start()可以正常工作。
    采用utf编码时,大部分编辑器都会在在文件头部附加一个BOM块,我的EditPlus附加的是FF FE,用16进制编辑器
    可以很清楚的看到。这样,当调用session_start()时,实际上已经向浏览器输出两个字节,只不过是不可见字符浏
    览器中出现如下警告:
    Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at ......................

    解决方法:
    1、手动去掉BOM块,可以在16进制编辑器如UltraEdit中编辑,或者采用编辑器自带的功能,好的编辑器一般提供选择是否去除BOM块。
    2、自己编写脚本更正,这要针对不同的编辑器,BOM头定义:
    UTF-8                                 EF BB BF
    UTF-16 Big Endian              FE FF
    UTF-16 Little Endian           FF FE
    UTF-32 Big Endian 00 00    FE FF
    UTF-32 Little Endian           FF FE 00 00

    申明

    非源创博文中的内容均收集自网上,若有侵权之处,请及时联络,我会在第一时间内删除.再次说声抱歉!!!

    博文欢迎转载,但请给出原文连接。

  • 相关阅读:
    【前端优化之拆分CSS】前端三剑客的分分合合
    ipad&mobile通用webapp框架前哨战
    如何判断一个DOM元素正在动画,一个CSS“阻塞”JS的例子
    关于前端框架升级与全站样式替换的简单建议
    【HTML5&CSS3进阶04】CSS3动画应该如何在webapp中运用
    【HTML5&CSS3进阶03】Jser与Csser如何一起愉快的翻新老组件
    【HTML5&CSS3进阶学习02】Header的实现·CSS中的布局
    【HTML5&CSS3进阶学习01】气泡组件的实现
    【模块化编程】理解requireJS-实现一个简单的模块加载器
    【小贴士】探一探javascript中的replace
  • 原文地址:https://www.cnblogs.com/Athrun/p/1713911.html
Copyright © 2011-2022 走看看