于如何判断Ajax请求说自

洋洋框架中还发咬定请求是否是ajax,以Yii为条例,判断是否是ajax请求而这么

Yii::app()->request->isAjaxRequest;

斯特性即表示是否也ajax请求,那么这是怎么样判断的啊?
顺藤摸瓜源码发现Yii::app()->request指于CHttpRequest类,但是这个类似里没
isAjaxRequest这个特性,这是干吗?搜索一下ajax关键字,发现来个法子:

 /**
 * Returns whether this is an AJAX (XMLHttpRequest) request.
 * @return boolean whether this is an AJAX (XMLHttpRequest) request.
 */
public function getIsAjaxRequest()
{
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&   $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
}

还发出个注释:

/**
* @property boolean $isAjaxRequest Whether this is an AJAX       (XMLHttpRequest) request.
*/

难道说跟魔术点子魔术变量有关?
搜了一晃 “PHP property”

抄到了此:链接

@property shows a “magic” property variable that is found inside the
class.
datatype should be a valid PHP type or “mixed.” phpDocumentor will
display the optional description unmodified, and defaults to “mixed”
if the datatype is not present.

The property is presumed to be available for both read and write operations. If the property is read-only, you should use the @property-read tag instead. If the property is write-only, use @property-write.

也就是说用@property标记的变量是魔术变量。
简短点说PHP在调用对象的某属性的时刻,当此特性不存的早晚会失掉实施_get方法,同样发生任何的好像之章程(_set等)【下划线实际是片独】
跟踪到Yii框架的CComponent类中,发现Yii将__get方法重写

/**
* Returns a property value, an event handler list or a behavior based on its name.
 * Do not call this method. This is a PHP magic method that we override
 * to allow using the following syntax to read a property or obtain event handlers:
 * <pre>
 * $value=$component->propertyName;
 * $handlers=$component->eventName;
 * </pre>
 * @param string $name the property name or event name
 * @return mixed the property value, event handlers attached to the event, or the named behavior
 * @throws CException if the property or event is not defined
 * @see __set
 */
public function __get($name)
{
    $getter='get'.$name;
    if(method_exists($this,$getter))
        return $this->$getter();
    elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
    {
        // duplicating getEventHandlers() here for performance
        $name=strtolower($name);
        if(!isset($this->_e[$name]))
            $this->_e[$name]=new CList;
        return $this->_e[$name];
    }
    elseif(isset($this->_m[$name]))
        return $this->_m[$name];
    elseif(is_array($this->_m))
    {
        foreach($this->_m as $object)
        {
            if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
                return $object->$name;
        }
    }
    throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
        array('{class}'=>get_class($this), '{property}'=>$name)));
}

也就是说,当调用Yii::app()->request->isAjaxRequest;时会尝试去执行
getIsAjaxRequest方法,果然,在CHttpRequest类中凡出之方式的:

/**
 * Returns whether this is an AJAX (XMLHttpRequest) request.
 * @return boolean whether this is an AJAX (XMLHttpRequest) request.
 */
public function getIsAjaxRequest()
{
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
}

暨这里框架的流水线走清楚了,然后我们来看看她是怎样判断是否为ajax请求的。
只要

$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';

就是证明是ajax请求,那么$_SERVER[‘HTTP_X_REQUESTED_WITH’]凡什么啊?
‘XMLHttpRequest’又表示正在什么?

搜了瞬间$_SERVER,文档中凡是如此说的:

$_SERVER is an array containing information such as headers, paths,
and script locations. The entries in this array are created by the web
server. There is no guarantee that every web server will provide any
of these; servers may omit some, or provide others not listed here.
That said, a large number of these variables are accounted for in the
» CGI/1.1 specification, so you should be able to expect those.

就是说$_SERVER是带有一多样条件信息,这些信息是出于web
server创建的,不保险每个web server都见面创造,才疏学浅,我连web
server指的是啊都无确定,是浏览器?还是服务器(apache/nginx)?从字面看是后世。但是要的源流可是浏览器。

抄了瞬间 XMLHttpRequest,有这么的讲述:

XMLHttpRequest对象好在无为服务器交由全体页面的情景下,实现部分更新网页。
当页面全部加载了后,客户端通过该目标为服务器请求数据,服务器端接受多少并处理后,向客户端反馈数据。
XMLHttpRequest 对象提供了针对 HTTP 协议的意的顾,包括做出 POST 和
HEAD 请求和常见的 GET 请求的力量。
XMLHttpRequest 可以合还是异步返回 Web
服务器的应,并且能因文件或者一个 DOM 文档形式返回内容。
尽管名为也 XMLHttpRequest,它并无限于和 XML
文档一起使用:它好收到任何款式之文本文档。

XMLHttpRequest 对象是称呼也 AJAX 的 Web 应用程序架构的一致桩根本力量。
暂行无这些,用chrome随便跟踪ajax一个请求:

图片 1

q.png

发觉于伸手头部中有诸如此类的平起:

X-Requested-With:XMLHttpRequest

要是非ajax请求中凡是没的,看来是浏览器就端好定义之了。

出于应用的是jQuery,所以当jQuery源码中搜了一晃,发现就无异执:

if ( !options.crossDomain && !headers["X-Requested-With"] ) {
       headers["X-Requested-With"] = "XMLHttpRequest";
}

立马段代码出现在jQuery.ajaxTransport(function( options ) )中
也就是说在jQuery中封装的ajax请求都见面添加这个头部。
那XMLHttpRequest来源清楚了,它而是怎到$_SERVER中错过之也罢?
经过查找资料发现,请求信息会于服务器(nginx/apache等)写副环境变量
以apache为例:
翻看apache的配置文件发现它载入了这个模块

LoadModule setenvif_module modules/mod_setenvif.so

假如这模块正是因客户端请求头字段设置环境变量。
简简单单的羁押了生说明,于是将apache的配置文件加上了马上句:

SetEnv HTTP_X_REQUESTED_WITH lk

将HTTP_X_REQUESTED_WITH 的价设置为”lk”
于是打印出$_SERVER变量是如此的

图片 2

w.png

好了,到此地,表面上的流水线就倒了,也即明白了凡怎么样判定ajax请求的。
大概归纳为

  • 浏览器端将一定的恳求头设置也一定值,做吧标识,每个浏览器端可能不同,服务端接收到晚用那写副环境变量,PHP去读取环境变量判断是否是ajax请求。

关于实现之底细则需看有关源码进一步地失去询问,这里就是未开展了。

相关文章