什么是Ajax
目錄
1.背景介紹
2.知識剖析
3.常見問題
4.解決方案
5.編碼實戰
6.擴展思考
7.參考文獻
8.更多討論
1.背景介紹
什么是Ajax?
AJAX即異步的JavaScript與XML技術,指的是一套綜合了多項技術的瀏覽器端網頁開發技術。
? ? ? ? ? ? ? ? ? ?
通過在后臺與服務器進行少量數據交換,Ajax可以使網頁實現異步更新。 這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。 傳統的網頁(不使用 Ajax)如果需要更新內容,必須重載整個網頁頁面。
2.知識剖析
傳統的請求方式
傳統的web應用程序中,用戶向服務器發送一個請求,然后等待,服務器接受到用戶的請求然后響應。在這段時間內,用戶會傻乎乎 的盯著一個空白頁面看。這是因為以往的傳輸方式為同步處理方式。長久以來我們對這種web交互模式已經習慣了,并且以使用者的角度來講已經覺得是理所當然的事情了。
Ajax的工作方式
和傳統的web應用不同,Ajax采取了異步交互避免了用戶請求-等待-應答交互方式的缺點。 Ajax在應用程序和服務器中引入了一個中間層---Ajax引擎,它是用Javascript編寫的,在一個隱藏的框架中運行。Ajax引擎負責呈現用戶界面,
? ? ? ? ? ? ? ? ? ? ? ? 以及代表用戶和服務器進行交互。Ajax引擎允許用戶和服務器進行異步的交互。用戶無需傻乎乎的盯著空白頁面。
2-2回調函數的理解
? ? ? ? ? ? ? ? ? ? ? ? 字面上的理解,回調函數就是一個參數,將這個函數作為參數傳到另一個函數里面,當那個函數執行完之后,再執行傳進去的這個函數。這個過程就叫做回調。顧名思義,回調,就是回頭調用的意思。主函數的事先干完,回頭再調用傳進來的那個函數。? ? ? ? ? ? ? ? ? ? ? ?
舉一個別人舉過的例子:約會結束后你送你女朋友回家,離別時,你肯定會說:“到家了給我發條信息,我很擔心你。” 對不,然后你女朋友回家以后還真給你發了條信息。小伙子,你有戲了。其實這就是一個回調的過程。你留了個參數函數(要求女朋友給你發條信息)給你女朋友,然后你女朋友回家,回家的動作是主函數。她必須先回到家以后,主函數執行完了,再執行傳進去的函數,然后你就收到一條信息了。
? ? ? ? ? ? ? ? ? ? //定義主函數,回調函數作為參數function A(callback) {
callback();
? ? ? ? ? ? ? ? ? ? console.log('我是主函數');
}
? ? ? ? ? ? ? ? ? ? //定義回調函數function B(){
? ? ? ? ? ? ? ? ? ? setTimeout("console.log('我是回調函數')", 3000);//模仿耗時操作}
? ? ? ? ? ? ? ? ? ? //調用主函數,將函數B傳進去A(B);
? ? ? ? ? ? ? ? ? ? //輸出結果
我是主函數
? ? ? ? ? ? ? ? ? ? 我是回調函數? ? ? ? ? ? ? ? ? ? ?
上面的代碼中,我們先定義了主函數和回調函數,然后再去調用主函數,將回調函數傳進去。定義主函數的時候,我們讓代碼先去執行callback()回調函數,但輸出結果卻是后輸出回調函數的內容。這就說明了主函數不用等待回調函數執行完,可以接著執行自己的代碼。所以一般回調函數都用在耗時操作上面。比如ajax請求,比如處理文件等。
2-3同源策略
? ? ? ? ? ? ? ? ? ? 瀏覽器有一個很重要的概念——同源策略(Same-Origin Policy)。所謂同源是指,域名,協議,端口相同。不同源的客戶端腳本(JavaScript、ActionScript)在沒明確授權的情況下,不能讀寫對方的資源。? ? ? ? ? ? ? ? ? ?
同源策略在web應用的安全模型中是一個重要概念。在這個策略下,web瀏覽器允許第一個頁面的腳本訪問第二個頁面里的數據,但是也只有在兩個頁面有相同的源時。源是由URI,主機名,端口號組合而成的。這個策略可以阻止一個頁面上的惡意腳本通過頁面的DOM對象獲得訪問另一個頁面上敏感信息的權限。對于普遍依賴于cookie維護授權用戶session的現代瀏覽器來說,這種機制有特殊意義。客戶端必須在不同站點提供的內容之間維持一個嚴格限制,以防丟失數據機密或者完整性。
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方法
// jQuery
$(document).ready(function () {
$("#login").on("click", function () {
$.post("/carrots-admin-ajax/a/login", {
name: $("#username").val(),
pwd: $("#password").val()
},
function (data) {
var data = JSON.parse(data);
if (data.message == "success") {
window.location.;
} else {
$(".info").text(data.message);
}
});
});
});
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.參考文獻
參考一:
? ? ? ? ? ? ? ? ? ? 什么是跨域
參考二:
? ? ? ? ? ? ? ? ? ? AngularJS中then和success的區別
參考三:
? ? ? ? ? ? ? ? ? ? Ajax常見問題
8.更多討論
討論時間到,歡迎大家提問!
鳴謝
感謝大家觀看
今天的分享就到這里啦,歡迎大家點贊、轉發、留言、拍磚~
技能樹.IT修真院???
? “我們相信人人都可以成為一個工程師,現在開始,找個師兄,帶你入門,掌控自己學習的節奏,學習的路上不再迷茫”。
? ?這里是技能樹.IT修真院,成千上萬的師兄在這里找到了自己的學習路線,學習透明化,成長可見化,師兄1對1免費指導。
? ?快來與我一起學習吧~http://www.jnshu.com/login/1/21109035