ajax 不重新加載整個(gè)網(wǎng)頁的情況下,更新部分網(wǎng)頁的技術(shù)
注意:ajax只有在服務(wù)器上運(yùn)行才能生效,我在本地一般用phpstudy
優(yōu)點(diǎn):
1、優(yōu)化用戶體驗(yàn)
2、承擔(dān)了一部分本該服務(wù)器端的工作,減輕了服務(wù)器端的壓力
3、優(yōu)化了服務(wù)器端和瀏覽器端的傳輸,減少了帶寬占用
缺點(diǎn):
1、不支持回退按鈕
2、對搜索引擎的支持比較弱
3、安全問題,暴露了與服務(wù)器端交互的細(xì)節(jié)
XMLHttpRequest 對象
1、可以向服務(wù)器端發(fā)起請求并處理響應(yīng),而不阻塞用戶
2、可以在不更新整個(gè)網(wǎng)頁的的情況下,更新部分內(nèi)容
如何使用ajax
1、創(chuàng)建XMLHttpRequest 對象
2、創(chuàng)建一個(gè)HTTP請求,并指定方式、URL(必填)
3、設(shè)置響應(yīng)HTTP請求狀態(tài)變化的函數(shù)
4、發(fā)起請求
創(chuàng)建XMLHttpRequest 對象的兩種方式:(兼容各瀏覽器)
1、完整版
//封裝兼容各瀏覽器的xhr對象 function createXhr(){ //IE7+,其他瀏覽器 if(typeof XMLHttpRequest!="undefined"){ return new XMLHttpRequest();//返回xhr對象的實(shí)例 }else if(typeof ActiveXObject!="undefined"){ //IE7及以下 //所有可能出現(xiàn)的ActiveXObject版本 var arr=["Microsoft.XMLHTTP","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP.2.0"]; var xhr; //循環(huán) for(var i=0,len=arr.length;i<len;i++){ try{ xhr=new ActiveXObject(arr[i]);//任意一個(gè)版本支持,即可退出循環(huán) break; }catch(e){ } } return xhr;//返回創(chuàng)建的ActiveXObject對象 }else{ //都不支持 throw new Error("您的瀏覽器不支持XHR對象!"); } }
2、簡略版
function createXhr(){ //IE7+,其他瀏覽器 if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else{ //IE7以下 return new ActiveXObject("Microsoft.XMLHTTP"); } }
測試是否創(chuàng)建成功
//創(chuàng)建XMLHttpRequest對象 var xhr=createXhr(); console.log(xhr);
.open(method, url, async) 初始化請求并準(zhǔn)備發(fā)送(只能對同一個(gè)域中使用相同端口和協(xié)議的URL發(fā)送請求)
method :get 或者 post( get 更快更簡單,但不能發(fā)送大量數(shù)據(jù),無法使用緩存文件,而且沒有 post 穩(wěn)定和可靠)
url :必填(文件在服務(wù)器上的位置,可以是任何類型,如.txt .xml .asp .php)
async:是否異步,true 異步,false 同步(同步時(shí),服務(wù)器處理完成之間瀏覽器必須等待;異步時(shí),服務(wù)器未處理完成前,瀏覽器可以進(jìn)行其他操作)
get 準(zhǔn)備請求直接加上參數(shù),post 準(zhǔn)備請求不在此加參數(shù)
//2、get創(chuàng)建請求 xhr.open("get","./server/slider.json?user=cyy&age=25",true); //post創(chuàng)建請求 xhr.open("post","./server/slider.json",true);
響應(yīng)XMLHttpRequest 對象狀態(tài)變化的函數(shù)
.onreadystatechange 檢測狀態(tài)變化的函數(shù)
.readyState==4 響應(yīng)內(nèi)容解析完成
.status>=2==&&.status<300 異步調(diào)用成功
.status==304 請求資源沒有被修改,可以使用瀏覽器的緩存
發(fā)送請求.send()
發(fā)送post請求需要傳入?yún)?shù)(以對象形式),發(fā)送get請求不需要,可以傳入null
post請求需要添加HTTP頭
.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
//get發(fā)送請求 xhr.send(null); //post發(fā)送請求 xhr.send({user:"cyy",age:25}); //設(shè)置post請求頭 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
獲取到服務(wù)器返回的數(shù)據(jù)
responseText 服務(wù)器返回的數(shù)據(jù)的字符串形式
responseXML 服務(wù)器返回的數(shù)據(jù)的兼容DOM的文檔數(shù)據(jù)對象(XML形式)
status 返回的狀態(tài)碼(如404表示沒找到,200表示已就緒)
status Text 狀態(tài)碼的字符串信息
//獲取服務(wù)器端返回的數(shù)據(jù) console.log(xhr.responseText);
查看network狀態(tài)
json 數(shù)據(jù)格式
全稱是javascript對象表示法,目的是為了取代笨重的XML格式
json 可以表示以下三種類型的值:
1、簡單值
與js語法相同,可以是字符串、數(shù)值、布爾值、null,但不支持undefined
字符串必須用雙引號表示,不能用單引號
數(shù)值必須是十進(jìn)制,不能是 NaN 和 Infinity
2、對象
鍵名必須放在雙引號中
同一個(gè)對象不應(yīng)該出現(xiàn)兩個(gè)同名屬性
3、數(shù)組
數(shù)組或者對象最后一個(gè)成員,后面不能加逗號
示例:slider.json
{ "code": 0, "slider": [ { "linkUrl": "http://www.baidu.com", "picUrl": "img/cat1.jpg" }, { "linkUrl": "http://www.baidu.com", "picUrl": "img/cat2.jpg" }, { "linkUrl": "http://www.baidu.com", "picUrl": "img/cat3.jpg" }, { "linkUrl": "http://www.baidu.com", "picUrl": "img/cat4.jpg" } ]}
.responseText 返回的數(shù)據(jù)是字符串,因此需要先轉(zhuǎn)為對象
使用.eval() 函數(shù)
//獲取服務(wù)器端返回的數(shù)據(jù)console.log(typeof xhr.responseText);//string//把字符串轉(zhuǎn)為對象console.log(eval("("+xhr.responseText+")"));
eval("("+xhr.responseText+")"); 的意思是強(qiáng)制轉(zhuǎn)化成json對象,之所以寫成 eval“("("+data+")");這種格式,原因是由于json是以”{}”的方式來開始以及結(jié)束的。在JavaScript中,它會(huì)被當(dāng)成一個(gè)語句塊來處理,所以必須強(qiáng)制性的將它轉(zhuǎn)換成一種表達(dá)式,加上圓括號的目的是迫使eval函數(shù)在處理JavaScript代碼的時(shí)候強(qiáng)制將括號內(nèi)的表達(dá)式轉(zhuǎn)化為對象,而不是作為語句來執(zhí)行,舉一個(gè)例子,例如對象字面量{},如若不加外層的括號,那么eval會(huì)將大括號識別為JavaScript代碼塊的開始和結(jié)束標(biāo)記,那么{}將會(huì)被認(rèn)為是執(zhí)行了一句空語句,所以下面兩個(gè)執(zhí)行結(jié)果是不同的:
console.log(eval("{}"));//undefined console.log(eval("({})"));//{}
還有 json 對象的兩個(gè)方法:
1、 JSON.parse() 用于將json字符串轉(zhuǎn)為對象
2、JSON.stringify 將一個(gè)值轉(zhuǎn)為JSON字符串
由于eval() 可以執(zhí)行不符合json格式的代碼,有可能會(huì)包含惡意代碼,所以不推薦使用,建議還是使用.parse()
data=JSON.parse(xhr.responseText);console.log(data.slider);
最后一步,渲染數(shù)據(jù)到頁面中
放出文件index.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>demo</title> <style> *{margin:0;padding:0;} .wrap{width:250px;height:250px;margin:50px auto;overflow:hidden;} .banner{height:250px;width:1000px;} .banner a{width:250px;height:250px;display: block;float: left;} .banner a img{width:250px;height:250px;display: block;} </style> <script src="jquery.js"></script></head><body> <div class="wrap"> <div class="banner" id="banner"></div> </div> <script> //封裝兼容各瀏覽器的xhr對象 function createXhr(){ //IE7+,其他瀏覽器 if(typeof XMLHttpRequest!="undefined"){ return new XMLHttpRequest();//返回xhr對象的實(shí)例 }else if(typeof ActiveXObject!="undefined"){ //IE7及以下 //所有可能出現(xiàn)的ActiveXObject版本 var arr=["Microsoft.XMLHTTP","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP.2.0"]; var xhr; //循環(huán) for(var i=0,len=arr.length;i<len;i++){ try{ xhr=new ActiveXObject(arr[i]);//任意一個(gè)版本支持,即可退出循環(huán) break; }catch(e){ } } return xhr;//返回創(chuàng)建的ActiveXObject對象 }else{ //都不支持 throw new Error("您的瀏覽器不支持XHR對象!"); } } //1、創(chuàng)建XMLHttpRequest對象 var xhr=createXhr(),data; //響應(yīng)XMLHttpRequest狀態(tài)變化的函數(shù) //onreadystatechange監(jiān)測狀態(tài)變化 xhr.onreadystatechange=function(){ if(xhr.readyState==4){//響應(yīng)內(nèi)容解析完成 if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ //xhr.status>=200&&xhr.status<300 表示交易成功 //xhr.status==304 表示緩存后未發(fā)生改變,因此可以從緩存中讀取 //獲取服務(wù)器端返回的數(shù)據(jù) //console.log(typeof xhr.responseText);//string //把字符串轉(zhuǎn)為對象 data=JSON.parse(xhr.responseText); //console.log(data.slider); //渲染數(shù)據(jù) renderData(); } } } //2、get創(chuàng)建請求 xhr.open("get","./server/slider.json?user=cyy&age=25",true); //get發(fā)送請求 xhr.send(null); //post創(chuàng)建請求 //xhr.open("post","./server/slider.json",true); //post發(fā)送請求 //xhr.send({user:"cyy",age:25}); //設(shè)置post請求頭 //xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //渲染數(shù)據(jù) function renderData(){ var imgs=data.slider,str=""; var banner=document.getElementById("banner"); for(var i=0,len=imgs.length;i<len;i++){ //console.log(imgs[i]); str+="<a href='"+imgs[i].linkUrl+"'><img src='"+imgs[i].picUrl+"'></a>"; } console.log(str); banner.innerHTML=str; } </script></body></html>
效果圖(大概就是模擬獲取輪播圖)
jquery的ajax方法:
$.ajax()
$.get()
$.post()
$.getJson()
//jquery的$.ajax() $.ajax({ url:"./server/slider.json", //請求地址 type:"post", //請求方式,默認(rèn)是get async:true, //異步同步,默認(rèn)是true異步 dataType:"json", //返回的數(shù)據(jù)格式 success:function(data){ //響應(yīng)成功的操作 JQRenderData(data.slider); //data是返回的數(shù)據(jù) } }); function JQRenderData(data){ var str=""; $.each(data,function(index,obj){ str+="<a href='"+obj.linkUrl+"'><img src='"+obj.picUrl+"'></a>"; }); $("#banner2").html(str); }
$.each( obj, function(index, value){ } ) 方法,遍歷對象或數(shù)組
index 數(shù)組索引或者對象屬性名
value 數(shù)組項(xiàng)或者對象屬性值
以下是用javascript 和 jqeury 兩種方式實(shí)現(xiàn)的代碼
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>demo</title> <style> *{margin:0;padding:0;} .wrap{width:250px;height:250px;margin:50px auto;overflow:hidden;} .banner{height:250px;width:1000px;} .banner a{width:250px;height:250px;display: block;float: left;} .banner a img{width:250px;height:250px;display: block;} </style> <script src="jquery.js"></script></head><body> <div class="wrap"> <div class="banner" id="banner"></div> </div> <div class="wrap"> <div class="banner" id="banner2"></div> </div> <script> //封裝兼容各瀏覽器的xhr對象 function createXhr(){ //IE7+,其他瀏覽器 if(typeof XMLHttpRequest!="undefined"){ return new XMLHttpRequest();//返回xhr對象的實(shí)例 }else if(typeof ActiveXObject!="undefined"){ //IE7及以下 //所有可能出現(xiàn)的ActiveXObject版本 var arr=["Microsoft.XMLHTTP","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP.2.0"]; var xhr; //循環(huán) for(var i=0,len=arr.length;i<len;i++){ try{ xhr=new ActiveXObject(arr[i]);//任意一個(gè)版本支持,即可退出循環(huán) break; }catch(e){ } } return xhr;//返回創(chuàng)建的ActiveXObject對象 }else{ //都不支持 throw new Error("您的瀏覽器不支持XHR對象!"); } } //1、創(chuàng)建XMLHttpRequest對象 var xhr=createXhr(),data; //響應(yīng)XMLHttpRequest狀態(tài)變化的函數(shù) //onreadystatechange監(jiān)測狀態(tài)變化 xhr.onreadystatechange=function(){ if(xhr.readyState==4){//響應(yīng)內(nèi)容解析完成 if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ //xhr.status>=200&&xhr.status<300 表示交易成功 //xhr.status==304 表示緩存后未發(fā)生改變,因此可以從緩存中讀取 //獲取服務(wù)器端返回的數(shù)據(jù) //console.log(typeof xhr.responseText);//string //把字符串轉(zhuǎn)為對象 data=JSON.parse(xhr.responseText); //console.log(data.slider); //渲染數(shù)據(jù) renderData(); } } } //2、get創(chuàng)建請求 xhr.open("get","./server/slider.json?user=cyy&age=25",true); //get發(fā)送請求 xhr.send(null); //post創(chuàng)建請求 //xhr.open("post","./server/slider.json",true); //post發(fā)送請求 //xhr.send({user:"cyy",age:25}); //設(shè)置post請求頭 //xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //渲染數(shù)據(jù) function renderData(){ var imgs=data.slider,str=""; var banner=document.getElementById("banner"); for(var i=0,len=imgs.length;i<len;i++){ //console.log(imgs[i]); str+="<a href='"+imgs[i].linkUrl+"'><img src='"+imgs[i].picUrl+"'></a>"; } console.log(str); banner.innerHTML=str; } </script> <script> //jquery的$.ajax() $.ajax({ url:"./server/slider.json", //請求地址 type:"post", //請求方式,默認(rèn)是get async:true, //異步同步,默認(rèn)是true異步 dataType:"json", //返回的數(shù)據(jù)格式 success:function(data){ //響應(yīng)成功的操作 JQRenderData(data.slider); //data是返回的數(shù)據(jù) } }); function JQRenderData(data){ var str=""; $.each(data,function(index,obj){ str+="<a href='"+obj.linkUrl+"'><img src='"+obj.picUrl+"'></a>"; }); $("#banner2").html(str); } </script></body></html>
什么是跨域:
同源策略:域名、協(xié)議、端口都相同
不符合同源策略的請求,就是跨域
跨域常用的解決方式:JSONP
JSONP :JSON with padding (填充式j(luò)son)
JSONP的原理:
直接用XMLHttpRequest 訪問不同域上的數(shù)據(jù)是不可以的,但是可以在頁面上引入不同域的 js 腳本(如 src 或者 href )
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>demo</title> <script src="jquery.js"></script></head><body> <script> /* 封裝JSONP 瀏覽器端給服務(wù)器端發(fā)送請求: http://www.baidu.com?jsonp=abc 服務(wù)器端響應(yīng)請求: abc(json數(shù)據(jù)) */ function myJSONP(url,callback){ if(!url) return;//如果沒有url,則停止 //用數(shù)組存儲10個(gè)字母 var arr=["a","b","c","d","e","f","g","h","i","j"], i1=Math.floor(Math.random()*arr.length),//隨機(jī)生成索引 i2=Math.floor(Math.random()*arr.length), i3=Math.floor(Math.random()*arr.length), name="mydata"+arr[i1]+arr[i2]+arr[i3];//隨機(jī)生成的請求函數(shù)名(屬性名) cbname="myJSONP."+name;//必須是函數(shù)名.請求函數(shù)名 //跨域url處理 //將請求函數(shù)名作為最后一個(gè)參數(shù)傳遞 if(url.indexOf("?")===-1){ //原來沒有參數(shù) url+="?jsonp="+cbname;//參數(shù)名可自定義(此處是jsonp) }else{ //原來有參數(shù) url+="&jsonp="+cbname; } console.log(url); //動(dòng)態(tài)創(chuàng)建script標(biāo)簽 var script=document.createElement("script"); //定義被腳本執(zhí)行的回調(diào)函數(shù) myJSONP[name]=function(data){ try{ callback && callback(data);//如果有回調(diào),則執(zhí)行回調(diào) }catch(e){ //報(bào)錯(cuò)時(shí) }finally{ //由于每次請求都會(huì)生成函數(shù)和script標(biāo)簽,長此以往會(huì)污染函數(shù) //因此每次結(jié)束時(shí)都要?jiǎng)h除函數(shù)及變量 delete myJSONP[name]; script.parentNode.removeChild(script); } } script.src=url; document.getElementsByTagName("head")[0].appendChild(script); } //發(fā)送跨域請求 myJSONP("http://class.imooc.com/api/jsonp",function(data){ console.log(data); }); </script></body></html>
頁面返回的數(shù)據(jù)
url演示
聯(lián)系客服