摘要:之所以不能跨域其實是因為受到同源策略的限制,只能讓它訪問同源下的數據,不能訪問不同源下的數據同源策略每個網站只能讀取同一來源的數據,這里的同一來源指的是主機名域名協議和端口號的組合。
一、Ajax的概念
Ajax是一種技術方案,但并不是一種新技術。它依賴的是現有的CSS/HTML/Javascript,而其中最核心的依賴是瀏覽器提供的XMLHttpRequest對象,是這個對象使得瀏覽器可以發出HTTP請求與接收HTTP響應。
Ajax:Asynchronous JavaScript and XML(異步js和XML)
異步js:js的代碼都是至到而下執行的,如果一塊代碼沒有執行完畢,那后面的代碼就不會執行。異步就是ajax可以做到不按順序執行;
ajax不光能夠處理XML格式的數據,還可以處理json、數組、字符串類型的數據;
XML:存儲數據的一種格式:
//XML的格式類型;
大力丸
18
714206204
daliwan@126.com
ajax到底能干嘛:
js與后端進行數據交互的一種技術,通過請求協商好的接口,來獲取到想要的數據
優點
傳輸數據時候會在本頁面請求服務器,不用跳轉頁面,從而減輕服務器壓力。做到實時驗證,減少用戶返工率并且優化用戶體驗
二、Ajax數據交互流程
創建一個ajax對象;
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的形式;
2.用JSON的方法:JSON.parse(aja.responseText)轉成真正的對象就可以用對象操作的方法去操作了;
四、XHR的兼容問題XMLHttpRequest是標準瀏覽器下的升級版本,IE6這些瀏覽器不支持;
IE6下用ActiveXObject(Microsoft.XMLHTTP)
//寫一個兼容性的函數,實現跨瀏覽器;
var ajax=null;
if(window.XMLHttpRequest){
ajax=new XMLHttpRequest;
}else{
ajax=new ActiveXObject(Microsoft.XMLHTTP)
};
五、get和post的區別
get方式
通過地址欄信息進行數據傳輸,傳輸的大小有限制;
不安全,用戶的所有信息都會暴露出來;
拼接數據的時候要用encodeURI轉一下碼,不然有中文就會亂碼;
> `encodeURI`把文字轉成符號;
decodeURI把符號轉成文字;
不用設置請求頭;
數據拼接在open方法里;
會有緩存問題;
post方式
通過send向服務器傳輸數據,理論上來說是沒有長度或體積限制;
相對來說安全,因為不直接暴露用戶信息;
不用轉碼,已經通過請求頭設置了數據格式,不會有亂碼;
數據要拼接在send方法里;
沒有緩存問題
在send()的前面需要設置一個請求頭(不設置要出錯);
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方法是一樣的;
六、同步與異步
同步
1、當send()方法調用后會等待服務器返回信息,如果服務器一直沒有響應,就會阻塞后面的代碼,后面的代碼就不會執行
2、后面的代碼執行受前面代碼的影響,前面的代碼沒跑通,后面的代碼就不會執行
異步
1、當send()方法調用后,就會執行后面的代碼,不用等待服務器的響應
2、后面的代碼執行不受前面代碼的影響
七、onreadystatechange與onload
ajax.readStateajax的運行步驟(第一步捕捉不到)
它的值為4的話說明AJAX已經運行完畢;
0 代表初始化,還沒調用open方法;
1 代表載入,已經調用send方法,正在發送請求;
2 代表載入完成,send方法已完成,已收到全部響應內容;
3 代表正在解析響應內容;
4 代表響應完成,可以在客戶端調用了;
ajax.status(狀態碼)
200是成功的;
404是錯誤的;
onreadStateChange
readstate的值發生變化就會觸發這個事件;
onload
所有請求成功完成后觸發,此時的readstata的值為4
IE(6,7,8)不支持
現在這個方法逐漸取代onreadstatechange這個方法了
ajax.onreadstatechange=function(){
if(ajax.readstate==4){ //服務區響應完成了;
if(ajax.status==200){ //服務器正常;
//這里放要執行的代碼;
}
}
}
八、封裝ajax函數
封裝ajax函數,傳進函數里面的參數其實是一個對象;
對象中包包含以下幾種數據,包含在一個對象里面:
URL:發送請求的地址,需要把請求發給誰;
method:發送請求的方法:get或者post;
dataType:響應之后返回的數據類型:JSON,XML,STRING;
data:請求的時候傳的數據(它是一個對象需要處理格式);
succ:成功之后的callback;
fail:失敗后的callback;
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上傳
上傳只能用 post 的方法,后臺要處理中文相關的問題;
ajax.upload.onprogress 上傳的進度事件;就是上傳的時候要做的事情;
ev.loaded 已經上傳的文件大小;
ev.total 總的文件大小;
通過這個可以做出來一個上傳的進度條;
用H5中的這個API;
files 上傳的選中的文件列表;
1.包括文件大小、類型、最后修改的時間等等;
FormData 用來創建與表單格式相同的數據,它是XHR的二級定義,是一個二進制的數據;低版本的瀏覽器不支持;
**我自己對于FormData的理解:
FormDate可以new出來一個實例,這個實例可以繼承它身上的append方法;這個操作放在ajax.open和ajax.send之間**
var formdata=new FormData();
//下面通過循環把選中的文件里面的額東西添加到這個對象身上;
for(var i=0;i
十、跨域的問題
概念:
兩個不同域名下的數據進行交互。Ajax之所以不能跨域其實是因為XMLHttpRequest受到同源策略的限制,只能讓它訪問同源下的數據,不能訪問不同源下的數據;
同源策略:
每個網站只能讀取同一來源的數據,這里的同一來源指的是主機名(域名)、協議(http/https)和端口號的組合。在沒明確授權的情況下,不能讀寫對方的資源,它是瀏覽器最核心也最基本的安全功能;
只要有一個不一樣就跨域;
解決跨域的方法:
在標準瀏覽器下XMLHttpRequest配合后端設置一個請求權限,在php里寫上 header("Access-Control-Allow-Origin:*");
服務器代理,缺點是后端開發的成本大;
iframe、flash、postMessage、WebSocket;
這些方法都不是最優的,下面提供一種方法叫做 jsonp
十一、jsonp
jsonp的概念(json+padding)
通過script標簽引入某些數據,是同步模式的,用script標簽做跨域的時候,不建議將數據提前加載,需要按需加載;
當需要數據的時候創建一個script標簽,將需要的數據放在src中,通過onload去監聽是否請求過來,請求完畢就調用傳回來的數據(異步加載);
jsonp不能用post請求,只能是get請求;
帶src屬性的