首页 > 编程 > html实体与网页编码

html实体与网页编码

2008年12月5日 发表评论 阅读评论

最近在解析一个天气预报的xml文件时,发现它里面所有的汉字都转化为了html实体(十进制表示的Unicode编码),这样做的好处就是不管网页的编码是什么,都可以正常的显示汉字,而不会出现乱码,当然也适用于其他字符集。在php中我们可以用mbstring的mb_convert_encoding函数实现这个正向及反向的转化。
如:

mb_convert_encoding ("你好", "HTML-ENTITIES", "gb2312");    //输出:你好
mb_convert_encoding ("你好", "gb2312", "HTML-ENTITIES");    //输出:你好 

可以查看这个页面:htmlentities.html, 不管选择什么网页编码,网页都能正常显示。

如果需要对整个页面转化,则只需要在php文件的头部加上这三行代码:

mb_internal_encoding("gb2312");  // 这里的gb2312是你网站原来的编码
mb_http_output("HTML-ENTITIES");
ob_start('mb_output_handler');

如果没有打开mbstring扩展,可以参考coolcode.cn上的这两篇文章:
在任意字符集下正常显示网页的方法
在任意字符集下正常显示网页的方法(续)

在asp中我们可以用下面这个函数来实现这个转化:

Function htmlentities(str)
    For i = 1 to Len(str)
        char = mid(str, i, 1)
        If AscW(char) > 0 then
            htmlentities = htmlentities & "&#" & Ascw(char) & ";"
        Else
            htmlentities = htmlentities & "&#" & (65536 + ascW(char)) & ";"
        End if
    Next
End Function 

在任意字符集下正常显示网页的方法

通常情况下,我们的网页要指定一个编码字符集,如 GB2312、UTF-8、ISO-8859-1 等,这样我们就可以在网页上显示我们指定编码的文字了。但是我们很可能会遇到这种情况,那就是我们可能希望在 ISO-8859-1 编码的网页上显示汉字,或者在 GB2312 编码的网页上显示韩文等。当然一种解决办法就是我们不用 ISO-8859-1 或者 GB2312 编码,而统统都采用 UTF-8 编码,这样我们只要在这种编码下,就可以混合显示各国文字了,这是现在很多网站采用的方法。

而我这里所说的并非上面这种方法,因为上面这种方法必须要指定字符集为 UTF-8 才可以,一旦用户手工指定为其他字符集,或者可能因为某些原因,那个字符集设置没起作用,而浏览器又没有正确自动识别的话,我们看到的网页还是乱码,尤其是在某些用框架作的网页中,某个框架中的页面如果字符集设置没起作用,在 firefox 中显示乱码而且还没法改变(我是说在不装RightEncode插件的情况下)。

而我这里介绍的方法即使是把网页指定为 ISO-8859-1 字符集,也能够正确显示汉字、日文等。原理很简单,就是把除了 ISO-8859-1 编码中前128个字符以外的所有其他的编码都用 NCR(Numeric character reference) 来表示。比如“汉字”这两个字,如果我们写成“汉字”这种形式,那么它在任意字符集下都可以正确显示。根据这个原理,我写了下面这个程序,它可以把现有的网页转化为在任意字符集下都能显示的网页。你只需要指定源网页的字符集和源网页,点提交按钮,就可以得到目标网页了。你也可以只转化某些文字,只需要把文字填写到文本框中,并指定这些文字原来的字符集,点提交按钮,就会在页面上面显示编码后的文字了。另外我还编写了 WordPress 的插件,现在我的 Blog 已经可以在任意字符集下都能正确显示了。

 0) {
    $data = nochaoscode($encode, file_get_contents($_FILES['file']['tmp_name']));
    header ("Content-type: application/octet-stream;");
    header ("Content-length: ".strlen($data));
    header ("Content-Disposition: attachment; filename=".$_FILES['file']['name']);
    echo $data;
} else {
    header ("Content-type: text/html; charset=UTF-8");
    if ($_POST['email']) {
        echo htmlentities(nochaoscode($encode, $_POST['email'], true));
    }
    else {
        echo htmlentities(nochaoscode($encode, $_POST['content']));
    }
?>
encode: file:
encode: content:
encode: email:

在任意字符集下正常显示网页的方法(续)

前几天写了一篇在任意字符集下正常显示网页的方法,里面介绍的很简单,就是把前128个字符以外的字符集都用 NCR 来表示,但是具体怎么转化我没有介绍,因为当时我觉得太简单了。但是后来发现有人问这个问题,这里就详细说明一下。
首先第一步是要把源字符集的字符串转化为 UTF-16 字符集,做这一步是因为 UTF-16 字符集中的每个字符都是两个字节,后面处理起来很容易,而如果在源字符集上直接做处理则很复杂。源字符集可以从原网页中的 meta 标签中获得,也可以单独指定,我的程序是让用户在表单中指定源字符集,因为我不能保证用户提交的文件就一定是 HTML 文件(其他文件也是可以的,比如这个 WordPress 的汉化包源文件是个 po 文件,它里面的内容也可以这样处理),而且即使是 HTML 文件,里面也不一定就有用于指定字符集的 meta 标签,所以通过表单单独指定字符集比较保险。你可能会觉得将一种字符集转化为另一种字符集很复杂,确实如此,如果自己来实现的话,确实非常麻烦,但是用 PHP 来做却很容易,因为它里面已经包含这样的函数了,你可以通过 iconv 函数很容易的来实现各种字符集之间的转化,如果你的机器上没有安装 iconv 扩展,你也可以使用 mb_convert_encoding 函数,如果 Multibyte String 扩展也没有安装,那就没办法了,因为你要自己实现那么多种编码的转化基本上是不可能的,除非你是顶级大牛!推荐使用 iconv,因为这个效率高,支持的字符集也更多。

做完上面那一步之后,接下来是以每两个字节为单位对字符串进行处理。这两个字节直接转化为数字就是 &#xxxxx; 中的 xxxxx,如果这个数字小于 128 就直接使用这个字符(注意这里就变成单字节了),否则就使用 &#xxxxx; 的形式。这里有一点要注意,就是当这个数字是 65279(16 进制的 0xFEFF)时,请把它忽略掉,因为这个是 Unicode 编码中的传输控制字符,而我们现在的字符串已经只有 iso-8859-1 编码中的前 128 个字符了,所以我们不需要它了。

好了,基本思路就是这样,下面是实现的程序:

函数的参数中,$encode 是源字符集,$str 是需要进行转化的字符串。返回结果是转化以后字符串。

补充:今天 Legend 告诉我一种更简单的方法,就是直接利用 mb_convert_encoding 函数。因为 mb_convert_encoding 支持一种叫做 HTML-ENTITIES 的编码格式,也就是 NCR 编码。用它就更简单了。

分类: 编程 标签: ,
  1. 2008年12月5日14:17 | #1

    我要转载
    哈哈

  1. 本文目前尚无任何 trackbacks 和 pingbacks.

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。直接点击评论上方的回复实现此功能