Zh:Tutorials:Character Encoding and xajax






Zh:Tutorials:Character Encoding and xajax

Contents

[edit] xajax字符编码介绍

Ajax技术当前面临的一个重大问题就是如何处理不同字符集编码的问题。所有Ajax异步交互所依赖的都是Javascript XmlHttpRequest对象,它只能以UTF-8编码发送数据,与你所设置的HTML字符集和文件头无关。

使xajax能够方便的使用非UTF-8字符集成为开发过程中的一个大问题。从xajax 0.2.3版开始,我们提供了一个功能,我们希望该功能能使xajax与字符编码能够更抽象,更易于编写代码,更易于维护。

对于程序员来说,解决国际化最好的方法就是设计、创建网站和数据库只使用UTF-8编码,因为不管你需要使用什么语言,UTF-8编码都能显示相应的字符。xajax默认使用UTF-8编码。尽管我们知道这是最理想的情况,通常合法的代码和其它环境下极有可能会需要使用其它的编码。

这儿有三种方法来设置xajax使用的字符编码:

[edit] 改变默认编码

在xajax.inc.php文件中,引用了一个常量XAJAX_DEFAULT_CHAR_ENCODING。外部这个常量被赋为UTF-8。你可以将它改为你需要的任何字符编码,xajax会用你赋的值取代它。

//define ('XAJAX_DEFAULT_CHAR_ENCODING', 'utf-8' );
define ('XAJAX_DEFAULT_CHAR_ENCODING''ISO-8859-1' );

[edit] 在实例化的时候设置字符编码

类xajax和类xajaxResponse的构造函数都接受一个参数用于实例构造时的字符编码。他们默认被设置为XAJAX_DEFAULT_CHAR_ENCODING的值。


xajax构造函数参数:

xajax($sRequestURI="",$sWrapperPrefix="xajax_",$sEncoding=XAJAX_DEFAULT_CHAR_ENCODING,$bDebug=false)


xajaxResponse构造函数参数:

xajaxResponse($sEncoding=XAJAX_DEFAULT_CHAR_ENCODING, $bOutputEntities=false)


在实例化时你可以告知xajax使用何种编码:

$xajax = new xajax("","xajax_",'ISO-8859-1');

当然,如果你使用xajax实例化时使用了某种编码,记住设置xajaxResponse同样的编码:

$objResponse = new xajaxResponse('ISO-8859-1');

[edit] 实例化后设置编码

类xajax和类xajaxResponse都包含一个方法setCharEncoding(),它被用于类实例化后的改变字符集的情况:

$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');

如果你使用setCharEncoding()方法来改变xajax对象的编码,那么记住xajaxResponse对象也要作相应改变,否则xajax不会正常工作。你可以象前一节一样在xajaxResponse实例化时设置编码,或者在实例化后使用setCharEncoding()方法设置。

$objResponse = new xajaxResponse();
$objResponse->setCharEncoding('ISO-8859-1');

[edit] 如果编码仍然不能生效

如果你仍然得到无效XML的错误信息,而且字符是用于显示,而非比较或是操作,那么你可以试试使用(要求你安装了PHP的mb_string扩展) xajax->outputEntitiesOn().

outputEntitiesOn()告知响应对象自动转换特殊字符为HTML实体,这样不在你当前指定字符集中的字符就会被转换。例如é 则会被转换为é 这样就与浏览器中显示的一样。

如果你使用MySQL数据库并且想输入/输出想要的字符,试试下面的PHP命令:

mysql_query("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'");
mysql_query("SET CHARACTER SET utf8");

同时记住在html/xhtml文档中你可能需要设置使用的字符集。大概类似下面的html:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

and something like this in xhtml:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

你可以使用php的header()函数确认你的文档是以utf-8编码传送的:

header("Content-type: text/html; charset=utf-8");

[edit] 解码问题

即便你使用以上方法将字符编码为其它字符集,XmlHttpRequest对象也总是以UTF-8编码发送数据,并且从Javascript传递到xajax注册过的PHP函数参数的值也会被编码为UTF-8。

从0.2.3版本开始,xajax内建将接收到的UTF-8数据解码的功能,而不管你使用的是什么字符编码。该解码功能默认是关闭的。你可以调用xajax类的decodeUTF8InputOn()方法将其打开:

$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8InputOn();

当打开解码功能后,xajax会检查PHP安装的模块寻求合适的转换编码模块,如果有的话就使用他们。如果没有的话你会得到一条报错信息。如果有效的话,无论你的编码是什么,你函数接收到的参数值都是被正确编码过的。

[edit] 小帖士

  • 无论何时尽可能使用UTF-8编码。
  • 如果你在xajax构造器函数或者使用$xajax->setCharEncoding()方法设置了字符编码,记住你的xajaxResponse实例里面同样设置。如果忘记在xajaxResponse里设置与xajax实例一样的编码,在IE中你会得到一个XML错误。
  • 与你设置的编码无关,由Javascript发送的数据始终以UTF-8进行编码。使用$xajax->decodeUTF8InputOn()方法允许将UTF-8编码自动解码为你设置的字符编码。

[edit] 例子

<?php
require ('xajax.inc.php');

function testEncoding($strText)
{
        $objResponse = new xajaxResponse('ISO-8859-1');
        $objResponse->addAssign("div1","innerHTML",$strText);
    
        return $objResponse;
}

$xajax = new xajax();
$xajax->setCharEncoding('ISO-8859-1');
$xajax->decodeUTF8InputOn();

$xajax->registerFunction("testEncoding");

$xajax->processRequests();
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <?php
        $xajax->printJavascript();
    ?>
</head>

<body>
    <div id="div1"></div>

    <form id="form1" onsubmit="return false;">
        <input type="text" value="Español" id="text1" name="text1" />
        <input type="submit" value="Submit" onclick="xajax_testEncoding(xajax.$('text1').value);" />
    </form>
</form>
</body>
</html>