摘要:發(fā)送后等待服務端響應,響應是以觸發(fā)事件來通知,隨后通過請求對象實例拿到狀態(tài)以及響應的內(nèi)容。表示服務器響應內(nèi)容的文本形式。而是在調(diào)用發(fā)出后,被調(diào)用者通過觸發(fā)事件,調(diào)用事件處理回調(diào)函數(shù)。
Ajax是什么
AJAX即“Asynchronous JavaScript and XML”(異步的JavaScript與XML技術),指的是一套綜合了多項技術的瀏覽器端網(wǎng)頁開發(fā)技術,包含了HTML、CSS、JavaScript、DOM、XML等技術。Aiax 只是一個哥們“發(fā)明”的縮寫,這個新術語用來描述一種使用現(xiàn)有技術集合的一個名稱。多項技術中最重要的是 XMLHttpRequest 對象,稍后會介紹到它。
如果不使用 Ajax,仔細觀察一個Form的提交,你就會發(fā)現(xiàn),一旦用戶點擊“Submit”按鈕,表單開始提交,瀏覽器就會刷新頁面,然后會跳到新頁面里告訴你操作是成功了還是失敗了。如果失敗了,還要返回表單填寫頁,有些信息會丟失,需要重新填寫,這對用戶體驗極其不友好。
這是Web的運作原理:一次HTTP請求對應一個頁面。
如果要讓用戶留在當前頁面中,同時發(fā)出新的HTTP請求,就必須用JavaScript發(fā)送這個新請求,接收到數(shù)據(jù)后,再用JavaScript更新頁面,這樣一來,用戶就感覺自己仍然停留在當前頁面,數(shù)據(jù)卻可以不斷地更新。
也就是說,當使用了 Ajax 后,可以在不重新刷新頁面的情況下與服務器通信,交換數(shù)據(jù),更新頁面, 這樣能夠快速地將數(shù)據(jù)更新呈現(xiàn)在用戶界面上,這使得程序能夠更快地回應用戶的操作。
可以利用 Ajax 的特性做如下事情:
在不重新加載頁面的情況下發(fā)送請求給服務器
接受并使用從服務器響應的數(shù)據(jù)。
交換的數(shù)據(jù)格式使用 AJAX 技術中的 XMLHttpRequest 對象與服務器通信,交換數(shù)據(jù)。數(shù)據(jù)的格式可以使用JSON,XML,HTML和文本等多種格式發(fā)送和接收。盡管X在Ajax中代表XML, 但由于JSON的許多優(yōu)勢,更加輕量以及是Javascript的一部分,目前JSON的使用比XML更加普遍。
關于JSONJSON(JavaScript Object Notation) 是一種輕級的數(shù)據(jù)交換格式。JSON實際上是JavaScript的一個子集。但是和JavaScript的語法稍微有些不同,有屬于JSON自己的語法。
JSON構建于兩種形式:
無序的“‘名稱/值’對”集合
一個對象以“{”(左括號)開始,“}”(右括號)結束。每個“名稱”后跟一個“:”(冒號);“‘名稱/值’ 對”之間使用“,”(逗號)分隔。
值的有序列表
一個數(shù)組以“[”(左中括號)開始,“]”(右中括號)結束。值之間使用“,”(逗號)分隔。
在JSON中值支持以下幾種數(shù)據(jù)類型:
number:和JavaScript的number完全一致,在JSON中數(shù)字不能以0開頭。
boolean:JavaScript的true或false;
string:JavaScript的string;
null:JavaScript的null;
array:JavaScript的Array表示方式——[];在JSON中結尾不能有逗號。
object:JavaScript的{ ... }表示方式。在JSON中結尾不能有逗號,key值必須加上雙引號。
在JavaScript中,可以直接使用JSON,JavaScript內(nèi)置了JSON的解析。
JSON 對象
JSON對象定義在全局,該對象包含了兩個方法,除了這兩個方法, JSON這個對象本身并沒有其他作用,也不能被調(diào)用或者作為構造函數(shù)調(diào)用。
JSON.stringify()
將 JavaScript 中的對象或數(shù)組序列化成JSON字符串。簡單來說 JSON 是 JavaScript 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質(zhì)是一個字符串。
序列化將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或傳輸?shù)男问降倪^程。
例如在 JavaScript 中定義的對象:
let obj = {a:1,b:2}
此對象存在于內(nèi)存中,并不能將期結構存儲在cookie或localStorage或傳遞給后端。而此時就需要調(diào)用此方法序列換為一個 JSON 字符串。
console.log(JSON.stringify(obj)); // {"a":1,"b":2}
JSON.parse()
將 JSON 字符串反序列化成 JavaScript 中的對象或數(shù)組。JSON 字符串本身只是一個字符串,不能通過屬性名的方式獲取對應的值。要轉(zhuǎn)換為對象就可以使用 key 來取值。
反序列化將可以存儲或傳輸?shù)男问睫D(zhuǎn)換為對象的過程。
例如從后端拿到一個 JSON 字符串 :
let objStr = "{"a":1,"b":2}"
此時不能使用 objStr.a 取到數(shù)值1,因為 objStr 本身只是一個字符串值,并不是對象。
需要把JSON 字符串轉(zhuǎn)成可用的對象:
console.log(JSON.parse(objStr)); // {"a":1,"b":2}異步
Ajax 中的Asynchronous 是異步的意思,結合 Ajax 可以和服務器進行通信,可以說Ajax是用JavaScript執(zhí)行異步的網(wǎng)絡請求。
所謂的異步就是,一個異步過程調(diào)用發(fā)出后,調(diào)用者不會立刻得到結果。而是在 調(diào)用 發(fā)出后,被調(diào)用者通過狀態(tài)、通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用。
其中DOM事件,定時器就是典型的異步操作。拿定時器舉例,當調(diào)用 setTimeout 函數(shù)時候,就發(fā)起了一個異步操作,此時不會立馬得到反饋,而到了設置的時間,會調(diào)用傳入的回調(diào)函數(shù),一旦回調(diào)函數(shù)執(zhí)行就得到通知說明異步完成了。
setTimeout(function(){ console.log("執(zhí)行此回調(diào)函數(shù),異步完成得到通知,該干嘛干嘛!!!"); }, 1000)
與之對應的還有一個同步的概念,所謂同步,就是在發(fā)出一個調(diào)用時,在沒有得到結果之前,該調(diào)用就不返回。但是一旦調(diào)用返回,就得到返回值了。由調(diào)用者主動等待這個調(diào)用的結果。
比如拿一個 JavaScript 中函數(shù)調(diào)用舉例:
var arr = [1,2,3,4,5,6,7,8]; arr.map((item) => { return item * 2 }) arr.forEach((item) => { return item * 2 })
上述代碼中只有 map 指向之后,得到了結果,才能繼續(xù)調(diào)用 forEach, 這是一個同步調(diào)用的過程。
在使用 Ajax 時候,發(fā)出的是一個異步請求,要通過調(diào)用函數(shù)獲得響應。
分解Ajax中的知識點使用 JavaScript 創(chuàng)建一個請求對象實例,調(diào)用該實例下的方法,設置好請求的URL地址和請求數(shù)據(jù),發(fā)送異步請求。發(fā)送后等待服務端響應,響應是以觸發(fā)事件來通知,隨后通過請求對象實例拿到HTTP狀態(tài)以及響應的內(nèi)容。
完成一次請求,代碼示意如下所示
let xhr = new XMLHttpRequest; console.log(xhr.readyState); // 0 UNSENT 創(chuàng)建實例對象,尚未調(diào)用open(); xhr.open("GET","http://kuapi.wykiss.cn/api?json=true",true); console.log(xhr.readyState); // 1 OPENED open()方法已成功調(diào)用。 // 當readyState狀態(tài)發(fā)生變化時,觸發(fā)此事件 xhr.onreadystatechange = function () { console.log(xhr.readyState); if(xhr.readyState === 2){ // 2 HEADERS_RECEIVED 可以獲取到響應頭信息 console.log("響應頭信息為:",xhr.getAllResponseHeaders()) }else if(xhr.readyState === 3){ // 3 LOADING 正在接收部分響應內(nèi)容 console.log("接收的部分內(nèi)容是:",xhr.response) }else if(xhr.readyState === 4) { // 4 DONE 請求操作已經(jīng)完成,響應的內(nèi)容全部接受完成 console.log("接收全部內(nèi)容是:",xhr.response) } } // 請求操作完成 觸發(fā)的事件 xhr.onload = function () { console.log("請求操作完成,觸發(fā)此事件") console.log("可以直接獲取響應的全部內(nèi)容",xhr.response) } xhr.send();
咋眼一看,內(nèi)容還挺多,分解每一個知識點如下。
XMLHttpRequest 對象XMLHttpRequest 是規(guī)范制定的API,已經(jīng)被現(xiàn)代瀏覽器廣泛使用,它為客戶端提供了在客戶端和服務器之間傳輸數(shù)據(jù)的功能,是Ajax技術的核心所在。
全局會提供一個 XMLHttpRequest 構造函數(shù)來初始化一個請求實例對象。
var xhr = new XMLHttpRequest();
此對象上會有多個屬性和方法。
readyState 屬性只讀屬性,xhr.readyState 記錄了請求實例對象運行過程中所處的狀態(tài),使用數(shù)字來表示。以下是每個數(shù)字代表的含義:
值 | 狀態(tài) | 描述 |
---|---|---|
0 | UNSENT | 請求對象已創(chuàng)建,尚未調(diào)用 open()方法 |
1 | OPENED | open()方法已成功調(diào)用 |
2 | HEADERS_RECEIVED | send() 方法已調(diào)用,可以獲取到響應頭信息 |
3 | LOADING | 正在接收部分響應內(nèi)容 |
4 | DONE | 請求操作已經(jīng)完成,響應的內(nèi)容全部接受完成 |
兩個都是只讀屬性,存的是服務器的響應內(nèi)容。 responseText表示服務器響應內(nèi)容的文本形式。
responseType 屬性可讀可寫屬性,xhr.responseType 表示響應的類型, 缺省為空字符串, 可取 "arraybuffer" , "blob" , "document" , "json" , and "text" 共五種類型。
當將responseType設置為一個特定的類型時,你需要確保服務器所返回的類型和你所設置的返回值類型是兼容的。那么如果兩者類型不兼容,服務器返回的數(shù)據(jù)變成了null,即使服務器返回了數(shù)據(jù)。還有一個要注意的是,給一個同步請求設置responseType會拋出一個InvalidAccessError 的異常。
xhr.responseURL 返回ajax請求最終的URL, 如果請求中存在重定向, 那么responseURL表示重定向之后的URL。
status 屬性只讀屬性。xhr.status存的是數(shù)字狀態(tài)碼,是標準的HTTML狀態(tài)碼。在請求完成前,status的值為0。如果請求出錯,瀏覽器返回的 status 也為0。如果服務器響應中沒有明確指定status碼, status碼將會默認為200。
statusText 屬性只讀屬性。xhr.status存的是服務器返回的狀態(tài)短語。這個屬性包含了返回狀態(tài)對應的文本信息,例如"OK"或是"Not Found"。
open() 方法xhr.open() 方法初始化一個請求。
語法:
xhr.open(method, url)
xhr.open(method, url, async)
method 要使用的HTTP方法,比如 「GET」、「POST」、「PUT」、「DELETE」等。常用的是「GET」、「POST」請求方式。其他的方法后端需要特別的支持。
接下來討論的是在瀏覽器應用層面中GET和POST發(fā)送數(shù)據(jù)的不同。
- GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以。 - GET請求只能進行url編碼,而POST支持多種編碼方式。 - GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會被保留。 - GET請求在URL中傳送的參數(shù)是有長度限制的,而POST么有。 - GET比POST更不安全,因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息。 - GET參數(shù)通過URL傳遞,POST放在Request body中。
url 發(fā)送請求的URL地址。如果發(fā)送的是 get 請求要把數(shù)據(jù)寫在地址欄的后面發(fā)送給后端。例如:
http://kuapi.wykiss.cn/api?js...
async 可選參數(shù)。默認為true,表示執(zhí)行是不是執(zhí)行異步操作。true,為異步,false,為同步。當設置false時,瀏覽器會出現(xiàn)一個警告。
異步請求發(fā)出后,調(diào)用者不會立刻得到結果。而是在 調(diào)用 發(fā)出后,被調(diào)用者通過觸發(fā)事件,調(diào)用事件處理回調(diào)函數(shù)。在沒有得到后端返回的結果之前,異步操作之后的代碼會繼續(xù)執(zhí)行。
// Ajax 發(fā)出異步請求 // ..... 代碼省略 console.log("沒得到結果,我先執(zhí)行");
同步請求發(fā)出后,在沒有得到結果之前,該調(diào)用就不返回。這就意味著,后續(xù)的代碼不能被執(zhí)行,只有等到同步調(diào)用結束后得到了結果,才能繼續(xù)執(zhí)行代碼。
// Ajax 發(fā)出同步請求 // ..... 代碼省略 console.log("只有同步操作完成后,我才能執(zhí)行");send() 方法
xhr.send() 方法用于發(fā)送 HTTP 請求。如果是異步請求(默認為異步請求),則此方法會在請求發(fā)送后立即返回,接著繼續(xù)執(zhí)行send后面的代碼;如果是同步請求,則此方法直到服務端響應結束后全部拿到響應的數(shù)據(jù)后才會返回。
xhr.send() 方法接受一個可選的參數(shù),其作為請求主體,發(fā)送 post 時會用到;如果請求方法是 GET,則應將請求主體設置為 null。
注意:請求方法為 post 時,要在請求頭(headers)中的 Content-Type 設置消息主體編碼方式,這樣服務端通常是根據(jù)請求頭(headers)中的 Content-Type 字段來獲知請求中的消息主體是用何種方式編碼,再對主體進行解析。
application/x-www-form-urlencoded
Content-Type 被指定為 application/x-www-form-urlencoded;提交的數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉(zhuǎn)碼。大部分服務端語言都對這種方式有很好的支持。例如 PHP 中,$_ POST[" json "] 可以獲取到 true 的值,$_POST["country"] 可以得到 中國 值。
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send("json=true&country=中國");
關于URL編碼
URL編碼是一種瀏覽器用來打包表單輸入的格式,瀏覽器從表單中獲取所有的name和其對應的value,將他們以name/value編碼方式作為URL的一部分或者分離的發(fā)送到服務器上。在 ajax 中要手動設置 Content-Type 為 application/x-www-form-urlencoded。
URL編碼規(guī)則:每對name/value由&分開,每對來自表單的name/value用=分開。如果用戶沒有輸入值的那個name依舊會出現(xiàn)不過就是沒有值。URL編碼是在字符ASCII碼的十六進制數(shù)的前面加上%。例如:中國 被轉(zhuǎn)成了 %E4%B8%AD%E5%9B%BD 。
onload 事件在ajax請求操作完成后觸發(fā), 觸發(fā)時機在 readyState==4 狀態(tài)之后,這時候返回的內(nèi)容已全部接受。
xhr.onload = function(){ var s = xhr.status; if((s >= 200 && s < 300) || s == 304){ var resp = xhr.responseText; //TODO ... } }onreadystatechange 事件
在readystate記錄的狀態(tài)改變時觸發(fā)。onreadystatechange 方法會被觸發(fā)4次。通常在事件處理函數(shù)中判斷 readystate 為4的情況下,才算全部接受到內(nèi)容。
xhr.onreadystatechange = function(e){ if(xhr.readyState==4){ var s = xhr.status; if((s >= 200 && s < 300) || s == 304){ var resp = xhr.responseText; //TODO ... } } }
以上是對Ajax知識點的總結,如有問題,歡迎指正!
擴展閱讀:
readyState狀態(tài)描述
https://xhr.spec.whatwg.org/#states
關于URL編碼
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
四種常見的 POST 提交數(shù)據(jù)方式:
https://imququ.com/post/four-ways-to-post-data-in-http.html
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96063.html
摘要:異常處理異常處理一直是回調(diào)的難題,而提供了非常方便的方法在一次調(diào)用中,任何的環(huán)節(jié)發(fā)生,都可以在最終的中捕獲到錯誤處理基本的小結具體的很多的用法可以參考阮一峰的入門教程,還有就是上面提到的電子書。 JS異步那些事 一 (基礎知識)JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers)JS異步那些事 五 (異步腳本...
摘要:異步那些事一基礎知識異步那些事二分布式事件異步那些事三異步那些事四異步那些事五異步腳本加載事件概念異步回調(diào)首先了講講中兩個方法和定義和用法方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式。功能在事件循環(huán)的下一次循環(huán)中調(diào)用回調(diào)函數(shù)。 JS異步那些事 一 (基礎知識)JS異步那些事 二 (分布式事件)JS異步那些事 三 (Promise)JS異步那些事 四(HTML 5 Web Workers...
閱讀 1526·2023-04-26 00:20
閱讀 1121·2023-04-25 21:49
閱讀 803·2021-09-22 15:52
閱讀 577·2021-09-07 10:16
閱讀 972·2021-08-18 10:22
閱讀 2664·2019-08-30 14:07
閱讀 2237·2019-08-30 14:00
閱讀 2651·2019-08-30 13:00