1.背景介紹
什么是Ajax曹阔?
AJAX即異步的JavaScript與XML技術(shù),指的是一套綜合了多項(xiàng)技術(shù)的瀏覽器端網(wǎng)頁開發(fā)技術(shù)隔披。?
通過在后臺(tái)與服務(wù)器進(jìn)行少量數(shù)據(jù)交換赃份,Ajax可以使網(wǎng)頁實(shí)現(xiàn)異步更新。 這意味著可以在不重新加載整個(gè)網(wǎng)頁的情況下锹锰,對(duì)網(wǎng)頁的某部分進(jìn)行更新芥炭。 傳統(tǒng)的網(wǎng)頁(不使用 Ajax)如果需要更新內(nèi)容漓库,必須重載整個(gè)網(wǎng)頁頁面。
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àn)橐酝膫鬏敺绞綖橥教幚矸绞缴蒲印iL久以來我們對(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)行異步的交互幽邓。用戶無需傻乎乎的盯著空白頁面。
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的問題
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)求的頁面返回的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í)候在測試Ajax代碼的時(shí)候加了 xhr.status==200的判斷后康吵,一直不執(zhí)行xhr.status==200的代碼, 這個(gè)就需要注意了访递。xhr.status==200是要通過服務(wù)器確認(rèn)后來返回的晦嵌,在服務(wù)器頁面沒有發(fā)生錯(cuò)誤或者轉(zhuǎn)向時(shí)才返回200狀態(tài)的, 此狀態(tài)和你通過瀏覽器訪問頁面時(shí)服務(wù)器定義的狀態(tài)一致。這個(gè)我們提前就跟后端對(duì)接好了惭载,問題也不大旱函。
5.編碼實(shí)戰(zhàn)
jQuery方法
// jQuery
$(document).ready(function(){? ? $("#login").on("click",function(){? ? ? ? $.post("/carrots-admin-ajax/a/login", {? ? ? ? ? ? ? ? name: $("#username").val(),? ? ? ? ? ? ? ? pwd: $("#password").val()? ? ? ? ? ? },function(data){vardata =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原生方法
varrequest =newXMLHttpRequest();// 新建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)的文本:returnsuccess(request.responseText);? ? ? ? ? ? ? ? ? ? ? ? ? }else{// 失敗陡舅,根據(jù)響應(yīng)碼判斷失敗原因:returnfail(request.status);? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? }else{// HTTP請(qǐng)求還在繼續(xù)...}? ? ? ? ? ? ? ? ? }
原生的講解
(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)建方式如下:
varxmlhttp;if(window.XMLHttpRequest)? ? ? ? ? ? ? ? ? ? ? {// code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=newXMLHttpRequest();? ? ? ? ? ? ? ? ? ? ? }else{// code for IE6, IE5xmlhttp=newActiveXObject("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ò)展思考
$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.更多討論
PPT:https://ptteng.github.io/WEB/ppt/js-05-ajax.html
騰訊視頻:https://v.qq.com/x/page/u0624fzwo87.html
今天的分享就到這里啦只泼,歡迎大家點(diǎn)贊剖笙、轉(zhuǎn)發(fā)、留言请唱、拍磚~