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