一、Ajax概述
1、Ajax介紹
(1)AJAX全稱:
Asynchronous: 異步(默認true) synchronous(同步false)
Javascript:核心技術(shù)還是js
And:
Xml:主要作為不同開發(fā)語言之間傳輸數(shù)據(jù)的標準(xml、json)
直譯:異步的javascript和xml
簡單的說Ajax就是一門可以與服務器進行異步或者是同步交互的一門技術(shù),可以實現(xiàn)頁面無刷新與服務器進行數(shù)據(jù)的交互。
簡單說,同步和異步交互就是在于代碼的執(zhí)行順序。
同步代碼按照順序運行,異步代碼不按照順序運行。
舉例說明:以同步或異步的方式去做飯
同步方式:只能等飯煮熟了后,再去炒菜或菜熟了再去煮飯。
異步方式:飯正在煮的時候,我們可以去炒菜。
顯然,異步方式編程效率更高效。
同步代碼會再造成代碼的阻塞,因為同步代碼在內(nèi)存棧區(qū)執(zhí)行,嚴格按照順序來執(zhí)行。異步代碼是不會阻塞的。且只有棧中同步代碼執(zhí)行完畢之后,才執(zhí)行異步的代碼。
2、Ajax實際應用場景
①無刷新搜索
②無刷新驗證郵箱或者手機號或者用戶名的唯一性
③無刷新分頁
好處:①減少數(shù)據(jù)庫服務器的壓力 ②提高用戶體驗
二、Ajax對象
1、創(chuàng)建ajax對象
創(chuàng)建Ajax對象的主要考慮主流的瀏覽器(W3C)還有低版本的IE瀏覽器.
主流W3C標準瀏覽器 (google,firefox,operate,高版本的IE瀏覽器,safari):
var xhr = new XMLHttpRequest(); 重點掌握,注意字母大小寫
低版本的IE瀏覽器(IE6,7,8)(了解即可)
var xhr = new ActiveXObject('Microsoft.XMLHTTP');
更低版本的IE瀏覽器(了解即可)
var xhr = new ActiveXObject("Msxml2.XMLHTTP");
代碼如下:
<title>Document</title>
<script type="text/javascript">
//主流瀏覽器創(chuàng)建ajax對象(google、firefox、高版本IE、safari)
var xhr = new XMLHttpRequest();
//低版本IE創(chuàng)建ajax對象
//var xhr = new ActiveXObject('Microsoft.XMLHTTP');
console.log(xhr);
</script>
2、封裝兼容瀏覽器通用的Ajax對象
a、通過try-catch實現(xiàn),代碼如下:
//封裝通用的ajax對象
function createXhr(){
var xhr = null;
try{
//主流瀏覽器
xhr = new XMLHttpRequest();
}catch(e){
//低版本IE
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//返回創(chuàng)建好的xhr對象
return xhr;
}
b、通過把創(chuàng)建ajax對象的方法名作為window全局對象的屬性判斷來實現(xiàn)。
使用的時候的,直接在html文件引入下面createXhr.js文件,調(diào)用上面封裝好的方法即可:
function createXhr(){
var xhr = null;
//先考慮主流的
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else if(window.ActiveXObject){
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}else{
alert('請升級您的瀏覽器,推薦安裝google瀏覽器');
}
//返回創(chuàng)建好的xhr對象
return xhr;
}
三、Ajax入門案例
1、使用Ajax的get請求獲取服務器響應數(shù)據(jù)
Ajax中的get請求的總結(jié)(四步曲)
第一步:創(chuàng)建ajax對象
第二步:給ajax的請求狀態(tài)改變,綁定監(jiān)聽的事件處理程序,在判斷狀態(tài)等于4且狀態(tài)碼等于200,接收服務端響應回來的數(shù)據(jù),處理自己的業(yè)務邏輯
第三步:建立一個http連接
第四步:發(fā)送http連接
2、使用Ajax發(fā)送POST請求獲取服務器響應數(shù)據(jù)
Ajax中的post請求的總結(jié)(五步曲)
第1步:創(chuàng)建ajax對象
第2步:給ajax的請求狀態(tài)改變,綁定監(jiān)聽的事件處理程序,在判斷狀態(tài)等于4且http狀態(tài)碼等于200,接收服務端響應回來的數(shù)據(jù),處理自己的業(yè)務邏輯
第3步:建立一個http連接
第4步:設置post請求頭,模擬post表單來傳遞數(shù)據(jù)給服務端(否則獲取不到send()中的參數(shù))
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
第5步:發(fā)送http連接
3、get和post請求總結(jié)
get是四步走,post是五步走。
get:其中有三步一定要按照如下順序:
1、創(chuàng)建ajax對象 new XMLHttpRequest
2、創(chuàng)建一個http請求 open
3、發(fā)送一個http請求 send
至于xhr.onreadystatechange = function(){}這一步,放在上面三步中的任意一步后面都可以,因為我們都可以捕獲到狀態(tài)等于4。建議,此步放在創(chuàng)建ajax之后,因為可以監(jiān)聽更多的狀態(tài)。
post:其中有四步一定要按照如下順序:
1、建ajax對象 new XMLHttpRequest
2、創(chuàng)建一個http請求 open
3、設置post請求頭 setRequestHeader
4、發(fā)送一個http請求 send
至于xhr.onreadystatechange = function(){}這一步,放在上面四步中的任意一步后面都可以,因為我們都可以捕獲到狀態(tài)等于4。建議,此步放在創(chuàng)建ajax之后,因為可以監(jiān)聽更多的狀態(tài)。
四、Ajax異步和同步運行的原理
Ajax同步:首先代碼從上到下按照執(zhí)行,如果遇到了同步的Ajax代碼段,只有等同步的Ajax程序執(zhí)行完畢之后,其后面的代碼才會執(zhí)行。若Ajax同步的代碼還沒執(zhí)行完畢,其后面的代碼是一直處于阻塞狀態(tài)。
Ajax異步:首先代碼從上到下依次執(zhí)行,如果是遇到異步的Ajax代碼段,則瀏覽器會新開一個線程去處理異步的Ajax代碼,對后面的代碼沒有影響,依然按順序執(zhí)行,即異步后面的代碼不會出現(xiàn)阻塞的情況。
特別注意,JavaScript引擎是在棧中單線程執(zhí)行js代碼,異步的ajax代碼是瀏覽器新開啟一個線程單獨去執(zhí)行異步代碼的,同步則不會開啟新線程。(瀏覽器是多線程的)

五、Ajax跨域
1、介紹
因為由于瀏覽器的同源(域)策略,禁止ajax從一個域名請求另外一個域名上的數(shù)據(jù)
2、如何才算跨域
如一個普通的url地址如下:
http://www.abc.com:80/index.html
我們可以把上面的url地址分為四個部分:
協(xié)議:http,https
一級(頂級)域名:abc.com baidu.com
二級域名:www.abc.com 、 blog.abc.com image.baidu.com
端口號:http協(xié)議默認是80端口,https默認是443
以上四個部分,ajax請求的時候只要有一個地方不一樣都算做跨域請求。
3、解決跨域的辦法
主要有以下三種解決方法:重點掌握通過php代理的形式完成跨域請求。
由于瀏覽器的同源策略影響,ajax只能訪問同域名下的文件,因此要是實現(xiàn)跨域一般有以下幾種方案:
?第一種:通過php代理去請求。



注:服務端語言php是沒有跨域限制的。
?第二種:通過CORS方式。
這是html5提供解決跨域限制的一種辦法。在請求的服務端頁面中設置以下響應頭即可,告訴瀏覽器可以跨域請求。
header(“Access-Control-Allow-Origin:*”); // *代表允許所有域名訪問
header(“Access-Control-Allow-Origin:http://native.com”); // 值只允許nativa.com訪問
一般不會使用CORS方式:IE10以下不支持。



?第三種:通過jsonp實現(xiàn),實質(zhì)通過script標簽的src屬性完成跨域。
jsonp只是一個約定跨域的形式。 跟json沒有關(guān)系。
jsonp跨域原理:
就是利用<script>標簽沒有跨域限制的,從而達到與第三方網(wǎng)站通訊的目的。當需要通訊時,本站(local.com)通過js創(chuàng)建一個<script>標簽,其src屬性值指向第三方網(wǎng)站(native.com)的一個php文件的地址。
特別注意:jsonp只針對get請求。
如:<script src="http://native.com/index.php?callback=fnName"></script>
本站(local.com)設置好一個js回調(diào)函數(shù)(fnName)
第三方網(wǎng)站(native.com)輸出一個js執(zhí)行函數(shù)的形式,并且傳遞json數(shù)據(jù)作為函數(shù)參數(shù)。(故稱之為jsonp,即json padding)

注:jsonp只針對get請求,跟ajax沒有關(guān)系
jsonp跨域代碼如下:
必須有兩個域名配合使用:
a、先去native.com域名上面建立一個jsonp.php的接口文件

b、再去local.com域名建立一個jsonp.html文件請求jsonp.php文件


問:還有哪些標簽可以跨域?
答:img-src、iframe-src、link-href、script-src
注意:如果是ajax請求,其type類型為xhr,是jsonp(js)類型,則type的值script

分析jd商品搜索跨域為例:

為什么jd網(wǎng)站會采用jsonp方式跨域呢?
答:jd會把不同的業(yè)務放在不同的服務器進行處理,這樣可以減輕單臺服務器的壓力。
推薦幾個常用的Api接口的網(wǎng)站: 聚合api: <u>https://www.juhe.cn/</u> apiStore: <u>http://apistore.baidu.com/</u>