显示标签为“Ajax”的博文。显示所有博文
显示标签为“Ajax”的博文。显示所有博文

星期五, 二月 27, 2009

CodeIgniter: is_ajax,判断 AJAX 请求

CakePHP 的 RequestHandler 组件,有一个方便的方法 isAjax ,可以判断当前的请求是否为 AJAX 请求。貌似 CodeIgniter(以下简称 CI) 没有)。不过不要紧, 可以自行对 CI 的类库进行扩展,添加上 is_ajax 方法(之所以用下划线分隔的方式命名而不是骆驼峰方式,是因为要迎合 CI 的开发规范)。

我们决定扩充 CI 的CI_Input 类,不赞成直接对核心代码的修改,既然 CI 提供了良好的扩充机制,为什么不用呢? :)

创建一个名为 MY_Input.php 的文件,放在自己的 App(默认是 aplication )/libraries 文件夹下。内容如下:


class MY_Input extends CI_Input {
function MY_Input() {
parent::CI_Input();
}

function isAjax() {
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']=="XMLHttpRequest");
}
}
// END Input class

/* End of file Input.php */
/* Location: ./system/application/MY_Input.php */

注意:具体的文件名,要根据你在 config.php 中对 $config['subclass_prefix'] 的设置。默认是 $config['subclass_prefix'] = ‘MY_’;

下面,就可以在 Controller 里对 Input 类自行加载使用:

......

function foo() {
$this->load->library('input');
if ($this->input->is_ajax()) {
do_something();
....
}
}
......

神奇的浏览器嗅探代码

在 shortest way to test for IE 一文中, 讲述了20个方法嗅探 IE 浏览器 ,其中:

ie = '\v'=='v';

上面的代码是不是很神奇,但重要的是,它确实正确地判断出 IE 浏览器。这是利用浏览器的特性来作出判断的。其它的利用浏览器特性判断的 JS 代码:

ie = !!top.execScript;
ie = /*@cc_on!@*/!1;
ie8 = !!window.XDomainRequest;
IEVersion = 0/*@cc_on+ScriptEngineMajorVersion()@*/;
ff = /a/[-1]=='a';
ff3 = (function x(){})[-5]=='x';
ff2 = (function x(){})[-6]=='x';
safari=/a/.__proto__=='//';
chrome=/source/.test((/a/.toString+''));
opera=/^function \(/.test([].sort);

在 Mootools 1.2.1 里,也是利用浏览器的特性来作出嗅探的:

if (window.opera) Browser.Engine = {
name: 'presto',
version: (document.getElementsByClassName) ? 950 : 925};
else if (window.ActiveXObject) Browser.Engine = {
name: 'trident',
version: (window.XMLHttpRequest) ? 5 : 4};
else if (!navigator.taintEnabled) Browser.Engine = {
name: 'webkit',
version: (Browser.Features.xpath) ? 420 : 419};
else if (document.getBoxObjectFor != null) Browser.Engine = {
name: 'gecko',
version: (document.getElementsByClassName) ? 19 : 18};

Browser.Engine[Browser.Engine.name] =
Browser.Engine[Browser.Engine.name + Browser.Engine.version] = true;