大家好,我是IT修真院成都分院第7期的學(xué)員韓建名,一枚正直純潔善良的WEB前端程序員。
目錄
1.背景介紹
2.知識(shí)剖析
3.常見問題
4.解決方案
5.編碼實(shí)戰(zhàn)
6.擴(kuò)展思考
7.參考文獻(xiàn)
8.更多討論
1.背景介紹
什么是Ajax?
AJAX即“Asynchronous JavaScript and XML”(異步的JavaScript與XML技術(shù)),指的是一套綜合了多項(xiàng)技術(shù)的瀏覽器端網(wǎng)頁(yè)開發(fā)技術(shù)。 Ajax的概念由杰西·詹姆士·賈瑞特所提出。
通過在后臺(tái)與服務(wù)器進(jìn)行少量數(shù)據(jù)交換,Ajax可以使網(wǎng)頁(yè)實(shí)現(xiàn)異步更新。 這意味著可以在不重新加載整個(gè)網(wǎng)頁(yè)的情況下,對(duì)網(wǎng)頁(yè)的某部分進(jìn)行更新。 傳統(tǒng)的網(wǎng)頁(yè)(不使用 Ajax)如果需要更新內(nèi)容,必須重載整個(gè)網(wǎng)頁(yè)頁(yè)面。
2.知識(shí)剖析
傳統(tǒng)的請(qǐng)求方式
傳統(tǒng)的web應(yīng)用程序中,用戶向服務(wù)器發(fā)送一個(gè)請(qǐng)求,然后等待,服務(wù)器接受到用戶的請(qǐng)求然后響應(yīng)。在這段時(shí)間內(nèi),用戶會(huì)傻乎乎 的盯著一個(gè)空白頁(yè)面看。這是因?yàn)橐酝膫鬏敺绞綖橥教幚矸绞?。長(zhǎng)久以來我們對(duì)這種web交互模式已經(jīng)習(xí)慣了,并且以使用者的角度來講已經(jīng)覺得是理所當(dāng)然的事情了。
Ajax的工作方式
和傳統(tǒng)的web應(yīng)用不同,Ajax采取了異步交互避免了用戶請(qǐng)求-等待-應(yīng)答交互方式的缺點(diǎn)。 Ajax在應(yīng)用程序和服務(wù)器中引入了一個(gè)中間層---Ajax引擎,它是用Javascript編寫的,在一個(gè)隱藏的框架中運(yùn)行。Ajax引擎負(fù)責(zé)呈現(xiàn)用戶界面, 以及代表用戶和服務(wù)器進(jìn)行交互。Ajax引擎允許用戶和服務(wù)器進(jìn)行異步的交互。用戶無需傻乎乎的盯著空白頁(yè)面。
3.常見問題
1、IE瀏覽器下面的緩存問題
2、跨域問題
3、Ajax亂碼問題
4、使用post提交的時(shí)候需要設(shè)置content-type為"application/x-www-form-urlencoded"
5、Ajax對(duì)象屬性的大小寫問題
6、Ajax狀態(tài)為0的問題
下面一一講解常見問題出現(xiàn)的原因和解決辦法
4.解決方案
第一個(gè)問題,緩存問題:
在IE瀏覽器下面使用get請(qǐng)求時(shí),如果第一次請(qǐng)求了數(shù)據(jù)之后IE會(huì)自動(dòng)緩存數(shù)據(jù),如果下一次再發(fā)送同樣的 請(qǐng)求的時(shí)候?yàn)g覽器會(huì)自動(dòng)先去找緩存顯示出來,所以如果請(qǐng)求的數(shù)據(jù)有變化的時(shí)候,這里是看不到變化的。 解決辦法:xhr.open("get","xxxx.aspx?_dc="+new Date().getTime(),true);就是在請(qǐng)求的后面 加上_dc=。。。讓url變成唯一,或者是,改成post請(qǐng)求。
第二個(gè)問題,跨域問題:
這是我們目前見到的最多的,也是最熟悉的一個(gè)問題。本地上面直接采用Nginx跨域?qū)崿F(xiàn)。在服務(wù)器上的話,交給后端吧。。。 注意 Nginx跨域可以同時(shí)配置多個(gè)接口的,就是多寫幾個(gè)location就好了,然后location后面帶的參數(shù)不一樣就可以了。
第三個(gè)問題: Ajax亂碼問題
亂碼問題雖然我們目前遇到的不多,但是也屬于比較常見的一個(gè)問題了。出現(xiàn)的主要原因就是編碼不一致導(dǎo)致的。 如果出現(xiàn)亂碼問題了,首先檢查一下meta聲明的charset要和請(qǐng)求的頁(yè)面返回的charset一致。response.charset="gb2312 or utf-8"
第四個(gè)問題:使用post提交的時(shí)候需要設(shè)置
content-Type: application/x-www-form-urlencoded; ? ? ? ? ? ? ? ? ? jQuery中,content-Type: application/x-www-form-urlencoded;charset=utf-8;
AngularJS中$http的content-Type: application/json; charset=utf-8;
使用原生Ajax需要在open以后才能使用xhr.setRequestHeader()方法,否則出錯(cuò)。 xhr.open("post","xxxx.aspx",true); xhr.setRequestHeader("content-type","application/x-www-form-urlencoded")
用原生寫時(shí)必須在open()方法之后send()方法之前調(diào)用。
第五個(gè)問題:Ajax對(duì)象屬性的大小寫問題,有些瀏覽器比如火狐,對(duì)大小寫是敏感的,if (xhr.readystate==4)這種寫法, 在IE下是成立的,但是在ff下就行不通了,因?yàn)镮E不區(qū)分大小寫,ff是區(qū)分大小的。標(biāo)準(zhǔn)寫法為if (xhr.readyState==4),同理還有屬性 responseText,responseXML。習(xí)慣采用駝峰形式的寫法可以避免這個(gè)問題。
第六個(gè)問題:Ajax狀態(tài)0的問題,有時(shí)候在測(cè)試Ajax代碼的時(shí)候加了 xhr.status==200的判斷后,一直不執(zhí)行xhr.status==200的代碼, 這個(gè)就需要注意了。xhr.status==200是要通過服務(wù)器確認(rèn)后來返回的,在服務(wù)器頁(yè)面沒有發(fā)生錯(cuò)誤或者轉(zhuǎn)向時(shí)才返回200狀態(tài)的, 此狀態(tài)和你通過瀏覽器訪問頁(yè)面時(shí)服務(wù)器定義的狀態(tài)一致。這個(gè)我們提前就跟后端對(duì)接好了,問題也不大。
5.編碼實(shí)戰(zhàn)
jQuery方法
$.ajax({
url:"student-ajax/student",
type:"POST",
dataType:"json",
data:{
name:$("#names").val(),
qq:$("#QQs").val(),
},
success:function(data){
console.log(data);
if(data.code === 200){
alert($("#names").val() + "學(xué)員信息" +data.message);
}else{
alert(data.message);
}
},
error:function(data){
console.log(data);
alert("添加失敗");
}
});
}) ;
AngularJS方法
$http({
method:'get',
url:('/a/a/all/document?type=1&page='+$scope.page),
headers:{'Content-Type':'application/x-www-form-urlencoded'}
})
.success(function (response) {
// console.log(12345);
console.log(response.total);
console.log(response);
console.log(aaa);
// if (response.message === "查詢成功") {
$scope.userList = response.data;
$scope.userTotal = response.total;
$scope.page=response.page;
// console.log($scope.userList.total);
});
Javascript原生方法
var request = new XMLHttpRequest(); // 新建XMLHttpRequest對(duì)象;
request.onreadystatechange = function () { // 狀態(tài)發(fā)生變化時(shí),函數(shù)被回調(diào);
if (request.readyState === 4) { // 成功完成
// 判斷響應(yīng)結(jié)果:
if (request.status === 200) {
// 成功,通過responseText拿到響應(yīng)的文本:
return success(request.responseText);
} else {
// 失敗,根據(jù)響應(yīng)碼判斷失敗原因:
return fail(request.status);
}
} else {
// HTTP請(qǐng)求還在繼續(xù)...
}
}
// 發(fā)送請(qǐng)求:
request.open("POST","/skill-ajax/a/login",true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send();
alert('請(qǐng)求已發(fā)送,請(qǐng)等待響應(yīng)...');
// readyState值說明
// 0,初始化,XHR對(duì)象已經(jīng)創(chuàng)建,還未執(zhí)行open
// 1,載入,已經(jīng)調(diào)用open方法,但是還沒發(fā)送請(qǐng)求
// 2,載入完成,請(qǐng)求已經(jīng)發(fā)送完成
// 3,交互,可以接收到部分?jǐn)?shù)據(jù)
// status值說明
// 200:成功
// 404:沒有發(fā)現(xiàn)文件、查詢或URl
// 500:服務(wù)器產(chǎn)生內(nèi)部錯(cuò)誤
原生的講解
(1) 在使用xhr對(duì)象發(fā)送請(qǐng)求和處理請(qǐng)求響應(yīng)之前,必須先用js語言創(chuàng)建一個(gè)xhr對(duì)象。由于xhr對(duì)象當(dāng)前還不是w3c標(biāo)準(zhǔn),所以才有多種方式進(jìn)行創(chuàng)建以解決兼容性問題。具體創(chuàng)建方式如下:
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
(2) 向服務(wù)器發(fā)送請(qǐng)求
(a) open(method,url,async) 規(guī)定請(qǐng)求的類型、URL 以及是否異步處理請(qǐng)求。
method:請(qǐng)求的類型;GET 或 POST
url:文件在服務(wù)器上的位置
async:true(異步)或 false(同步)
(b)send(string)
將請(qǐng)求發(fā)送到服務(wù)器。
string:僅用于 POST 請(qǐng)求
6.擴(kuò)展思考
AngularJS請(qǐng)求的時(shí)候,success()和then()方法的區(qū)別?
$http({
url:'data.json',
method:'GET'
}).success(function(data,header,config,status){
//code goes here
}).error(function(data,header,config,status) {
//code goes here
});
var promise = $http({
url:'data.json',
method:'GET'
});
promise.then(function(resp) {
//resp是一個(gè)響應(yīng)對(duì)象
}, function() {
//帶有錯(cuò)誤信息的resp
})
then()方法與其他兩種方法的主要區(qū)別是,它會(huì)接收到完整的響應(yīng)對(duì)象,信息更為全面,而success()和error()則會(huì)對(duì)響應(yīng)對(duì)象進(jìn)行析構(gòu),使用起來更為方便。
7.參考文獻(xiàn)
參考一:什么是跨域
參考二:AngularJS中then和success的區(qū)別
參考三:Ajax常見問題
8.更多討論