Ajax:Asynchronous JavaScript and XML(異步js和XML)javascript
//XML的格式類型; <name>大力丸</name> <age>18</age> <qq>714206204</qq> <email>daliwan@126.com</email>
js與後端進行數據交互的一種技術,經過請求協商好的接口,來獲取到想要的數據php
傳輸數據時候會在本頁面請求服務器,不用跳轉頁面,從而減輕服務器壓力。作到實時驗證,減小用戶返工率而且優化用戶體驗java
var val=inputs[0].value; //下面這個是ajax對象; var ajax=new XMLHttpRequest;
//open是ajax對象上的一個方法; ajax.open("get","php/get.php?user="+val,true); //第一個參數決定是get仍是post方式; //第二個參數是請求地址,而且把要提交的加上去; //第三個參數true表明異步,false表明同步;
ajax.send();
ajax.onload=function(){ //響應好了就接受數據; span.innerHTML=ajax.responseText; }
ajax.responseText這是服務器返回的值:
1.確定是字符串,有的看起來是對象,實際上是json的形式;ajax
2.用JSON的方法:JSON.parse(aja.responseText)
轉成真正的對象就能夠用對象操做的方法去操做了;json
//寫一個兼容性的函數,實現跨瀏覽器; var ajax=null; if(window.XMLHttpRequest){ ajax=new XMLHttpRequest; }else{ ajax=new ActiveXObject(Microsoft.XMLHTTP) };
get方式後端
拼接數據的時候要用encodeURI
轉一下碼,否則有中文就會亂碼;跨域
> `encodeURI`把文字轉成符號;
decodeURI
把符號轉成文字;數組
post方式瀏覽器
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//建立對象; var ajax=null; if(window.XMLHttpRequest){ ajax=new XMLHttpRequest; }else{ ajax=new ActiveXObject(Microsoft.XMLHTTP) }; //填寫請求地址; ajax.open("post","php/post.php",true); //發送請求,要在send前設置一下請求頭; ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); ajax.send("user="+val) //下面的步驟和get方法是同樣的;
一、當
send()
方法調用後會等待服務器返回信息,若是服務器一直沒有響應,就會阻塞後面的代碼,後面的代碼就不會執行
二、後面的代碼執行受前面代碼的影響,前面的代碼沒跑通,後面的代碼就不會執行緩存
一、當
send()
方法調用後,就會執行後面的代碼,不用等待服務器的響應
二、後面的代碼執行不受前面代碼的影響
ajax.readState
ajax的運行步驟(第一步捕捉不到)
ajax.status
(狀態碼)
onreadStateChange
readstate
的值發生變化就會觸發這個事件;
onload
全部請求成功完成後觸發,此時的
readstata
的值爲4
IE(6,7,8)不支持
如今這個方法逐漸取代onreadstatechange
這個方法了
ajax.onreadstatechange=function(){ if(ajax.readstate==4){ //服務區響應完成了; if(ajax.status==200){ //服務器正常; //這裏放要執行的代碼; } } }
封裝ajax函數,傳進函數裏面的參數實際上是一個對象;
對象中包包含如下幾種數據,包含在一個對象裏面:
function ajax(json){ //默認參數; var settings={ url:"", method:"get", data:{}, dataType:"json", succ:null, fail:null } //用戶傳的參數覆蓋默認參數; for (var attr in json){ settings[attr]=json[attr]; } //把data拼成正確的格式; var arr=[]; for (var attr in settings.data){ arr.push(attr+"="+settings.data[attr]); } settings.data=arr.join("&"); //聲明變量; var ajax=window.XMLHttpRequest?new XMLHttpRequest():ActiveXObject("Microsoft.XMLHTTP"); //設置請求方式; //請求地址裏面的new Date()方法,是爲了設置不一樣的時間戳去解決緩存的問題; if(settings.method.toLocalLowCase==="get"){ ajax.open("get",settings.url+"?"+settings.data+"&"+new Date().getTime(),true); ajax.send(); }else{ ajax.open("post",settings.url,true); //注意要設置一個請求頭; ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); ajax.send(settings.data); } //設置完成時間的兼容性;IE6下是沒有ajax.onload方法的; if(typeof ajax.onload==="undefined"){ ajax.onreadystatechange=ready; }else{ ajax.onload=ready; } //封裝一個ready()函數; function ready(){ if(ajax.readystate==4){ if(ajax.status==200){ //用一個switch判斷返回值得類型; switch(settings.dataType.toLocalLowCase()){ case "string" : settings.succ(ajax.responseText); break; case "json" : //把responsetext轉成json格式; setting.succ(JSON.parse(ajax.responseText)); break; case "xml" : settings.succ(ajax.responseXml); break; } }else{ settings.fail(ajax.status); } } } }
要注意第57行的JSON.parse在低版本的瀏覽器中是不兼容的,須要下載一個json2.js的文件解決這個問題;
ajax.upload.onprogress 上傳的進度事件;就是上傳的時候要作的事情;
ev.loaded
已經上傳的文件大小;ev.total
總的文件大小;經過這個能夠作出來一個上傳的進度條;
用H5中的<progress></progress>
這個API;
files 上傳的選中的文件列表;
1.包括文件大小、類型、最後修改的時間等等;
**我本身對於FormData的理解:
FormDate能夠new出來一個實例,這個實例能夠繼承它身上的append方法;這個操做放在ajax.open
和ajax.send
之間**
var formdata=new FormData(); //下面經過循環把選中的文件裏面的額東西添加到這個對象身上; for(var i=0;i<inputs[0].files.length;i++){ //inputs[0]指的是一個type="file"的表單控件; formdata.append("file",inputs[0].files[i]); } //這時候formdata就能夠被髮送給服務器了,前面加上一個請求頭;
兩個不一樣域名下的數據進行交互。Ajax之因此不能跨域實際上是由於XMLHttpRequest受到同源策略的限制,只能讓它訪問同源下的數據,不能訪問不一樣源下的數據;
每一個網站只能讀取同一來源的數據,這裏的同一來源指的是主機名(域名)、協議(http/https)和端口號的組合。在沒明確受權的狀況下,不能讀寫對方的資源,它是瀏覽器最核心也最基本的安全功能;
只要有一個不同就跨域;
解決跨域的方法:
這些方法都不是最優的,下面提供一種方法叫作 jsonp
jsonp的概念(json+padding)
帶src屬性的<script><img><iframe><link>等標籤是不須要遵照同源策略的,可是經過src加載的資源,瀏覽器限制了javascript的權限,能讀不能寫;這就是jsonp能實現跨域的緣由;
jsonp中的回調函數
請求到的結果是這樣的getData({"color":["red","green","blue"]})
注意callback是要設置成全局的,要不就放在操做的前面;
function jsonp(obj){ var settings={ url:'', //地址 data:{}, //要發送的數據 callBack:'callback', //url裏存儲回調函數名字的變量 fnName:'jsonp_'+new Date().getTime(), //回調函數的名字 succ:function(){} //請求成功的回調函數 }; for(var attr in obj){ settings[attr]=obj[attr]; } //建立一個script標籤 var script=document.createElement("script"); script.className='sc'; settings.data[settings.callBack]=settings.fnName; var head=document.getElementsByTagName('head')[0]; //把要傳的數據拼起來 var arr=[]; //['wd=sds','cb=jQuery1'] for(var attr in settings.data){ arr.push(attr+'='+settings.data[attr]); } settings.data=arr.join('&'); script.src=settings.url+'?'+settings.data; head.appendChild(script); //把回調函數掛載到window身上 window[settings.fnName]=function(data){ //當調用這個函數的時候,先把頁面中全部的已經請求過的script刪掉 var scripts=head.getElementsByTagName('script'); for(var i=0;i<scripts.length;i++){ if(scripts[i].className=='sc'){ head.removeChild(scripts[i]); } } settings.succ(data); }; }