Ajax与302

2014年08月20日

HTTP 302

302 Found是HTTP协议中的一个状态码(Status Code)。可以简单的理解为该资源原本确实存在,但已经被临时改变了位置;或者换个说法,就是临时的存在于某个临时URL下。通常会发送Header来暂时重定向到新的新位置。(维基百科)

Ajax与302响应

在ajax请求中,如果服务器端的响应是302 Found,在ajax的回调函数中是无法获取这个状态码的。在ajax的complete()与error()回调函数中得到的状态码都是404,而不是302。

原因是当服务器将302响应发给浏览器时,浏览器并不是直接进行ajax回调处理,而是先执行302重定向——从Response Headers中读取Location信息,然后向Location中的Url发出请求,在收到这个请求的响应后才会进行ajax回调处理。大致流程如下:

ajax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback

由于302返回的重定向URL在服务器上没有相应的处理程序(302直接被浏览器处理了),所以在ajax回调函数中得到的是404状态码;如果存在对应的URL,得到的状态码就是200。

所以,如果你想在ajax请求中根据302响应通过location.href进行重定向是不可行的。

问题来源

流量Go后台编码的时候发现使用ajax请求时,如果遇到session过期,那就无法正常重定向,而且会报错。

解决办法: ①直接用form提交,不用ajax ②通过jquery发送ajax请求网页内容时,它会向服务器传递一个HTTP_X_REQUESTED_WITH的参数,这个参数的值是XMLHttpRequest。

beforeSend: function (XMLHttpRequest) {
	XMLHttpRequest.setRequestHeader("X_Requested_With", 		"XMLHttpRequest");
} 参数名X_Requested_With,参数值XMLHttpRequest,你可以任意定义。Php取得时候要在参数名前面加上大写的http字样(即一个“HTTP_”前缀)然后“X_Requested_With”这个变量全部大写(一定要大写),然后再$_SERVER这个超级变量中找就可以了。

//php判断是否是ajax请求
public static function isAjaxRequest() {
    if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 		strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        return TRUE;
    } else {
        return FALSE;
    }
}

参考链接

302响应访问

PHP判断一个请求是Ajax请求还是普通请求访问

$_SERVER 判断页面是否为Ajax请求访问