PHP判斷ajax請求的原理:
在發送ajax請求的時候,我們可以通過XMLHttpRequest這個對象,創建自定義的 header頭信息, 在jquery框架中,對於通過它的$.ajax, $.get, or $.post方法請求網頁內容時,它會向服務器傳遞一個HTTP_X_REQUESTED_WITH的參數,php中就是在header一層判斷是否是 ajax請求,對應的根據$_SERVER['HTTP_X_REQUESTED_WITH']判斷。
/** * 當前請求是否ajax請求 * * @access public * @return bool */ function isAjax() { return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'XMLHttpRequest'; }
- 一般情況下$_SERVER['HTTP_X_REQUESTED_WITH']默認是XMLHttpRequest
- $_SERVER['HTTP_X_REQUESTED_WITH']也可以自定義創建的,使用XMLHttpRequest.setRequestHeader(name,value);參考文章:http://www.skygq.com/2011/01/04/php-check-request-from-ajax-or-normal/
PHP判斷AJAX請求時跨域問題:
如果是跨域的話這個,上面的isAjax就完全不正確了。跨域同域的問題參考:《$.getjson遇到的幾個問題》使用$.getJSON來實現跨域,但是檢測是否是ajax一直是false,並嘗試$get(參看:$.get實現返回解析json數據以及jsonp跨域)之后無果的之后,考慮要使用萬能的$ajax方法,見ajax的文檔:
如 果指定了script或者jsonp類型,那么當從服務器接收到數據時,實際上是用了<script>標簽而不是 XMLHttpRequest對象。這種情況下,$.ajax()不再返回一個XMLHttpRequest對象,並且也不會傳遞事件處理函數,比如 beforeSend。
解釋:
ajax跨域只能指定jsonp格式的數據,這個是就不是XMLHttpRequest對象了,就算你自定義一個$_SERVER['HTTP_X_REQUESTED_WITH']也是沒有意義的
解決的辦法:
針對跨域情況的getjson 或者ajax(jsonp)可以使用ACCEPT請求頭部格式來判斷
PHP端對應$_SERVER['HTTP_ACCEPT']
jsonp的請求一般是:text/javascript, application/javascript, */*
json的請求:application/json, text/javascript, */*
一個簡單的判斷跨域條件下的ajax請求:
switch ($_SERVER['HTTP_ACCEPT']){ case 'application/json, text/javascript, */*': // JSON 格式 break; case 'text/javascript, application/javascript, */*': // javascript 或 JSONP 格式 break; case 'text/html, */*': // HTML 格式 break; case 'application/xml, text/xml, */*': // XML 格式 break; }