一臭增、Ajax概述
1、Ajax介紹
(1)AJAX全稱:
Asynchronous: 異步(默認(rèn)true) synchronous(同步false)
Javascript:核心技術(shù)還是js
And:
Xml:主要作為不同開發(fā)語言之間傳輸數(shù)據(jù)的標(biāo)準(zhǔn)(xml各墨、json)
直譯:異步的javascript和xml
簡單的說Ajax就是一門可以與服務(wù)器進(jìn)行異步或者是同步交互的一門技術(shù),可以實(shí)現(xiàn)頁面無刷新與服務(wù)器進(jìn)行數(shù)據(jù)的交互。
簡單說启涯,同步和異步交互就是在于代碼的執(zhí)行順序欲主。
同步代碼按照順序運(yùn)行,異步代碼不按照順序運(yùn)行逝嚎。
舉例說明:以同步或異步的方式去做飯
同步方式:只能等飯煮熟了后扁瓢,再去炒菜或菜熟了再去煮飯。
異步方式:飯正在煮的時(shí)候补君,我們可以去炒菜引几。
顯然,異步方式編程效率更高效挽铁。
同步代碼會(huì)再造成代碼的阻塞伟桅,因?yàn)橥酱a在內(nèi)存棧區(qū)執(zhí)行,嚴(yán)格按照順序來執(zhí)行叽掘。異步代碼是不會(huì)阻塞的楣铁。且只有棧中同步代碼執(zhí)行完畢之后,才執(zhí)行異步的代碼更扁。
2盖腕、Ajax實(shí)際應(yīng)用場景
①無刷新搜索
②無刷新驗(yàn)證郵箱或者手機(jī)號(hào)或者用戶名的唯一性
③無刷新分頁
好處:①減少數(shù)據(jù)庫服務(wù)器的壓力 ②提高用戶體驗(yàn)
二赫冬、Ajax對(duì)象
1、創(chuàng)建ajax對(duì)象
創(chuàng)建Ajax對(duì)象的主要考慮主流的瀏覽器(W3C)還有低版本的IE瀏覽器.
主流W3C標(biāo)準(zhǔn)瀏覽器 (google,firefox,operate,高版本的IE瀏覽器,safari):
var xhr = new XMLHttpRequest(); 重點(diǎn)掌握溃列,注意字母大小寫
低版本的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對(duì)象(google劲厌、firefox、高版本IE听隐、safari)
var xhr = new XMLHttpRequest();
//低版本IE創(chuàng)建ajax對(duì)象
//var xhr = new ActiveXObject('Microsoft.XMLHTTP');
console.log(xhr);
</script>
2补鼻、封裝兼容瀏覽器通用的Ajax對(duì)象
a、通過try-catch實(shí)現(xiàn)雅任,代碼如下:
//封裝通用的ajax對(duì)象
function createXhr(){
var xhr = null;
try{
//主流瀏覽器
xhr = new XMLHttpRequest();
}catch(e){
//低版本IE
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//返回創(chuàng)建好的xhr對(duì)象
return xhr;
}
b风范、通過把創(chuàng)建ajax對(duì)象的方法名作為window全局對(duì)象的屬性判斷來實(shí)現(xiàn)。
使用的時(shí)候的沪么,直接在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('請(qǐng)升級(jí)您的瀏覽器,推薦安裝google瀏覽器');
}
//返回創(chuàng)建好的xhr對(duì)象
return xhr;
}
三成玫、Ajax入門案例
1加酵、使用Ajax的get請(qǐng)求獲取服務(wù)器響應(yīng)數(shù)據(jù)
Ajax中的get請(qǐng)求的總結(jié)(四步曲)
第一步:創(chuàng)建ajax對(duì)象
第二步:給ajax的請(qǐng)求狀態(tài)改變,綁定監(jiān)聽的事件處理程序哭当,在判斷狀態(tài)等于4且狀態(tài)碼等于200猪腕,接收服務(wù)端響應(yīng)回來的數(shù)據(jù),處理自己的業(yè)務(wù)邏輯
第三步:建立一個(gè)http連接
第四步:發(fā)送http連接
2钦勘、使用Ajax發(fā)送POST請(qǐng)求獲取服務(wù)器響應(yīng)數(shù)據(jù)
Ajax中的post請(qǐng)求的總結(jié)(五步曲)
第1步:創(chuàng)建ajax對(duì)象
第2步:給ajax的請(qǐng)求狀態(tài)改變陋葡,綁定監(jiān)聽的事件處理程序,在判斷狀態(tài)等于4且http狀態(tài)碼等于200彻采,接收服務(wù)端響應(yīng)回來的數(shù)據(jù)腐缤,處理自己的業(yè)務(wù)邏輯
第3步:建立一個(gè)http連接
第4步:設(shè)置post請(qǐng)求頭,模擬post表單來傳遞數(shù)據(jù)給服務(wù)端(否則獲取不到send()中的參數(shù))
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
第5步:發(fā)送http連接
3肛响、get和post請(qǐng)求總結(jié)
get是四步走岭粤,post是五步走。
get:其中有三步一定要按照如下順序:
1特笋、創(chuàng)建ajax對(duì)象 new XMLHttpRequest
2剃浇、創(chuàng)建一個(gè)http請(qǐng)求 open
3、發(fā)送一個(gè)http請(qǐng)求 send
至于xhr.onreadystatechange = function(){}這一步猎物,放在上面三步中的任意一步后面都可以虎囚,因?yàn)槲覀兌伎梢圆东@到狀態(tài)等于4。建議蔫磨,此步放在創(chuàng)建ajax之后淘讥,因?yàn)榭梢员O(jiān)聽更多的狀態(tài)。
post:其中有四步一定要按照如下順序:
1堤如、建ajax對(duì)象 new XMLHttpRequest
2蒲列、創(chuàng)建一個(gè)http請(qǐng)求 open
3窒朋、設(shè)置post請(qǐng)求頭 setRequestHeader
4、發(fā)送一個(gè)http請(qǐng)求 send
至于xhr.onreadystatechange = function(){}這一步嫉嘀,放在上面四步中的任意一步后面都可以炼邀,因?yàn)槲覀兌伎梢圆东@到狀態(tài)等于4魄揉。建議剪侮,此步放在創(chuàng)建ajax之后,因?yàn)榭梢员O(jiān)聽更多的狀態(tài)洛退。
四瓣俯、Ajax異步和同步運(yùn)行的原理
Ajax同步:首先代碼從上到下按照?qǐng)?zhí)行,如果遇到了同步的Ajax代碼段兵怯,只有等同步的Ajax程序執(zhí)行完畢之后彩匕,其后面的代碼才會(huì)執(zhí)行。若Ajax同步的代碼還沒執(zhí)行完畢媒区,其后面的代碼是一直處于阻塞狀態(tài)驼仪。
Ajax異步:首先代碼從上到下依次執(zhí)行,如果是遇到異步的Ajax代碼段袜漩,則瀏覽器會(huì)新開一個(gè)線程去處理異步的Ajax代碼绪爸,對(duì)后面的代碼沒有影響,依然按順序執(zhí)行宙攻,即異步后面的代碼不會(huì)出現(xiàn)阻塞的情況奠货。
特別注意,JavaScript引擎是在棧中單線程執(zhí)行js代碼座掘,異步的ajax代碼是瀏覽器新開啟一個(gè)線程單獨(dú)去執(zhí)行異步代碼的递惋,同步則不會(huì)開啟新線程。(瀏覽器是多線程的)
五溢陪、Ajax跨域
1萍虽、介紹
因?yàn)橛捎跒g覽器的同源(域)策略,禁止ajax從一個(gè)域名請(qǐng)求另外一個(gè)域名上的數(shù)據(jù)
2、如何才算跨域
如一個(gè)普通的url地址如下:
http://www.abc.com:80/index.html
我們可以把上面的url地址分為四個(gè)部分:
協(xié)議:http,https
一級(jí)(頂級(jí))域名:abc.com baidu.com
二級(jí)域名:www.abc.com 形真、 blog.abc.com image.baidu.com
端口號(hào):http協(xié)議默認(rèn)是80端口,https默認(rèn)是443
以上四個(gè)部分,ajax請(qǐng)求的時(shí)候只要有一個(gè)地方不一樣都算做跨域請(qǐng)求杉编。
3、解決跨域的辦法
主要有以下三種解決方法:重點(diǎn)掌握通過php代理的形式完成跨域請(qǐng)求没酣。
由于瀏覽器的同源策略影響王财,ajax只能訪問同域名下的文件,因此要是實(shí)現(xiàn)跨域一般有以下幾種方案:
?第一種:通過php代理去請(qǐng)求裕便。
注:服務(wù)端語言php是沒有跨域限制的绒净。
?第二種:通過CORS方式。
這是html5提供解決跨域限制的一種辦法偿衰。在請(qǐng)求的服務(wù)端頁面中設(shè)置以下響應(yīng)頭即可挂疆,告訴瀏覽器可以跨域請(qǐng)求改览。
header(“Access-Control-Allow-Origin:*”); // *代表允許所有域名訪問
header(“Access-Control-Allow-Origin:http://native.com”)缤言; // 值只允許nativa.com訪問
一般不會(huì)使用CORS方式:IE10以下不支持宝当。
?第三種:通過jsonp實(shí)現(xiàn),實(shí)質(zhì)通過script標(biāo)簽的src屬性完成跨域胆萧。
jsonp只是一個(gè)約定跨域的形式庆揩。 跟json沒有關(guān)系。
jsonp跨域原理:
就是利用<script>標(biāo)簽沒有跨域限制的跌穗,從而達(dá)到與第三方網(wǎng)站通訊的目的订晌。當(dāng)需要通訊時(shí),本站(local.com)通過js創(chuàng)建一個(gè)<script>標(biāo)簽蚌吸,其src屬性值指向第三方網(wǎng)站(native.com)的一個(gè)php文件的地址锈拨。
特別注意:jsonp只針對(duì)get請(qǐng)求。
如:<script src="http://native.com/index.php?callback=fnName"></script>
本站(local.com)設(shè)置好一個(gè)js回調(diào)函數(shù)(fnName)
第三方網(wǎng)站(native.com)輸出一個(gè)js執(zhí)行函數(shù)的形式羹唠,并且傳遞json數(shù)據(jù)作為函數(shù)參數(shù)奕枢。(故稱之為jsonp,即json padding)
注:jsonp只針對(duì)get請(qǐng)求,跟ajax沒有關(guān)系
jsonp跨域代碼如下:
必須有兩個(gè)域名配合使用:
a佩微、先去native.com域名上面建立一個(gè)jsonp.php的接口文件
b缝彬、再去local.com域名建立一個(gè)jsonp.html文件請(qǐng)求jsonp.php文件
問:還有哪些標(biāo)簽可以跨域?
答:img-src喊衫、iframe-src跌造、link-href、script-src
注意:如果是ajax請(qǐng)求族购,其type類型為xhr,是jsonp(js)類型,則type的值script
分析jd商品搜索跨域?yàn)槔?/p>
為什么jd網(wǎng)站會(huì)采用jsonp方式跨域呢壳贪?
答:jd會(huì)把不同的業(yè)務(wù)放在不同的服務(wù)器進(jìn)行處理,這樣可以減輕單臺(tái)服務(wù)器的壓力寝杖。
推薦幾個(gè)常用的Api接口的網(wǎng)站: 聚合api: <u>https://www.juhe.cn/</u> apiStore: <u>http://apistore.baidu.com/</u>