AJAX 是 Asynchronous JavaScript And XML 的簡稱,它可讓頁面在不刷新的狀況下從服務器獲取數據。javascript
瀏覽器使用XMLHttpRequest
對象於服務器通訊,它可使用JSON,XML,HTML和text等格式發送和接收數據。php
低版本 IE 瀏覽器沒有XMLHttpRequest
對象,可是它可使用ActiveXObject
對象代替。java
if (window.XMLHttpRequest) { // IE7+
XHR = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6
XHR = new ActiveXObject("Microsoft.XMLHTTP");
}
複製代碼
建立 XHR 實例事後就能夠監聽該實例的狀態改變事件onreadystatechange
,它會在 XHR 實例的readyState
的值改變時觸發回調函數。web
XHR.onreadystatechange = function () { }
複製代碼
而後咱們就可使用open
方法初始化一個請求和send
方法發送 HTTP 請求。ajax
XHR.open('GET', 'http://q.com')
// open 方法一共有 5 個參數,method, url, async, user, password 後三個可選。
// async 表示此次是否異步請求,默認是 true
XHR.send()
// send 方法接受一個可選參數 請求主體。
// 參數能夠是 FormData, FormData, ArrayBuffer, Document, 序列化字符串
複製代碼
若是是post
方法,就要在send
以前設置請求頭的Content-Type
。json
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 它接受兩個參數 header 和 value
複製代碼
而後咱們就要處理服務器返回的數據,回到onreadystatechange
函數。它監聽readyState
屬性的變化,而它一共有 5 個值。跨域
0
表示 請求還未初始化,還沒有調用 open() 方法。1
表示 已創建服務器連接,open() 方法已經被調用。2
表示 請求已接受,send() 方法已經被調用,而且頭部和狀態已經可得到。3
表示 正在處理請求,下載中; responseText 屬性已經包含部分數據。4
表示 完成,下載操做已完成。咱們還須要關心status
屬性它也是隻讀屬性,它是此次響應中的 HTTP 數字狀態碼。在請求以前和 XMLHttpRequest 出錯時它爲0
。數組
responseText
屬性是實際的數據,它是字符串,若是相應是 JSON 格式,須要用 JSON 的 parse 處理。瀏覽器
XHR.onreadystatechange = function () {
if (XHR.readyState === 4 && XHR.status === 200) {
console.log(JSON.parse(XHR.responseText))
}
}
複製代碼
若是服務器返回的是 XML, 咱們能夠用responseXML
屬性得到數據。緩存
// 若是已指明,responseType 必須是空字符串或 "docuemnt"
XHR.responseType = 'document';
// overrideMimeType() 用來強制解析 response 爲 XML
XHR.overrideMimeType('text/xml');
// --------------
var root = XHR.responseXML.getElementsByTagName('root').item(0)
複製代碼
responseType
屬性是一個枚舉類型的屬性,返回響應數據的類型。
withCredentials
屬性是一個Boolean類型,它指示了是否該使用相似cookies,authorization headers(頭部受權)或者TLS客戶端證書這一類資格證書來建立一個跨站點訪問控制請求。
(在IE中,超時屬性可能只能在調用 open() 方法以後且在調用 send() 方法以前設置)
abort
方法用來終止請求
getAllResponseHeaders
方法返回全部的響應頭
getResponseHeader(name)
方法返回包含指定頭文本的字符串
XMLHttpRequset 2 增長了一些新功能。好比能發送FormData
。
超時時間
timeout
屬性是超時時間,單位毫秒。當超時發生時他會觸發ontimeout
回調函數。
xhr.open('GET', '/server')
xhr.timeout = 2000
xhr.ontimeout = function (e) {}
xhr.send(null);
複製代碼
還有 6 個進度事件。
loadstart
在收到響應的第一個字節觸發progress
在接收期間不斷觸發error
發生錯誤abort
調用abort方法而終止load
接收到完整數據loadend
在通訊完成或abort error load事件後觸發有load
事件就不用readystatechange
事件和讀取readyState
屬性。
xhr.addEventListener("progress", updateProgress, false);
xhr.addEventListener("load", transferComplete, false);
xhr.addEventListener("error", transferFailed, false);
xhr.addEventListener("abort", transferCanceled, false);
function updateProgress(event) {
if (event.lengthComputable) {
console.log(`${event.position} / ${event.totalSize}`)
}
}
複製代碼
其中progress
的事件對象多了三個屬性。
lengthComputable
布爾值 表示進度信息是否可用position
已經接收到的字節數totalSize
根據Content-Length預期的字節數同源策略限制了從同一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。
當前網址(http://news.a.com)和請求網址
https://news.a.com
不一樣協議http://news.a.com:8080
不一樣端口http://home.a.com
不一樣域名時就不是同源。
爲了使 ajax 能夠從不一樣的網址獲取數據。
咱們可使用跨域資源共享(CORS)來解決問題。
在發送請求時會有個Origin
頭表示請求頁面的源信息, 若是服務器返回的Access-Control-Allow-Origin
中有相同的源信息或是*
那麼就能夠跨域請求信息,請求和響應都不包含cookie
。
CORS經過Preflighted Requests
透明服務器驗證機制支持使用自定義頭部、get和post以外的方法,不一樣類型的主題內容。
這種請求已OPTIONS方法發送,下面是它發送的頭信息:
Origin
源
Access-Control-Request-Method
請求自身使用的方法
Access-Control-Request-Headers
自定義頭部信息,用逗號分隔
發送請求後,服務器來決定是否容許,服務器會發送以下信息與瀏覽器溝通:
Access-Control-Allow-Origin
容許的源
Access-Control-Allow-Methods
容許的方法,逗號分隔
Access-Control-Allow-Headers
容許的頭部,逗號分隔
Access-Control-Allow-Max-Age
Preflight請求緩存的時間(秒)
默認狀況下跨域不提供cookie、HTTP認證、SSL證實,經過withCredentials
屬性設置爲true
能夠指定某個請求因該發送憑據。 服務器若是接收請求會返回Access-Control-Allow-Credentials
爲true
的頭信息。
還有一種方法是使用JSONP
。
jsonp
方法主要是建立script
標籤來得到數據,通常經過請求後面跟?callback=fn 回掉函數來獲取數據。
Fetch 是網絡請求的一個更好的替代方法。相比於 XMLHttpRequest,Fetch 寫法更簡單,功能更強大。
fetch('http://a.com')
.then(function(response) {
if (response.ok) {
return response.json();
}
throw new Error('err')
})
.then(function(myJson) {
console.log(myJson);
})
.catch(err => {
console.log(err)
})
複製代碼
fetch 函數接受兩個參數,返回一個 Promise 對象 。
第一個參數是 URL 或 Request 對象。第二個參數是可選一個配置項對象。
{
method: 'GET', // 請求方法
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
}, // 頭信息
body: JSON.stringify({data: 1}), // 請求的 body 信息,Blob, FormData 等
mode: 'cors', // 請求的模式,cors、 no-cors 或 same-origin
credentials: 'include', // omit、same-origin 或 include。爲了在當前域名內自動發送 cookie, 必須提供這個選項
cache: 'no-cache', // default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached
redirect: 'follow', // 可用的 redirect 模式: follow (自動重定向), error (若是產生重定向將自動終止而且拋出一個錯誤), 或者 manual (手動處理重定向).
referrer: 'no-referrer', // no-referrer、client或一個 URL。默認是 client。
referrerPolicy: 'no-referrer', // 指定 referer HTTP頭
integrity: 'sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=', // 包括請求的 subresource integrity 值
}
複製代碼
then 的回調函數接受一個 Response 對象。Response 實現了 Body(表明響應/請求的正文,容許你聲明其內容類型是什麼以及應該如何處理。)
它有 9 個屬性。
type
只讀 包含Response的類型 (例如, basic, cors)url
只讀 包含Response的URLuseFinalURL
包含了一個布爾值來標示這是不是該Response的最終URLstatus
只讀 包含Response的狀態碼ok
只讀 包含了一個布爾值來標示該Response成功(狀態碼200-299)edirected
只讀 表示該Response是否來自一個重定向,若是是的話,它的URL列表將會有多個statusText
只讀 包含了與該Response狀態碼一致的狀態信息headers
只讀 包含此Response所關聯的Headers 對象bodyUsed
Body 只讀 包含了一個布爾值來標示該Response是否讀取過Body8 個方法
clone
建立一個Response對象的克隆error
返回一個綁定了網絡錯誤的新的Response對象redirect(url, status)
用另外一個URL建立一個新的 responseBody(都返回一個 Promise 實例)
arrayBuffer
接受一個 Response 流, 並等待其讀取完成. 並 resolve 一個 ArrayBuffer 對象blob
blob()方法使用一個 Response 流,並將其讀取完成formData
將 Response 對象中的所承載的數據流讀取並封裝成爲一個對象json
使用一個 Response 流,並將其讀取完成。解析結果是將文本體解析爲 JSONtext
提供了一個可供讀取的"返回流", 它返回一個包含USVString對象,編碼爲UTF-8WebSockets 是一種先進的技術。它能夠在用戶的瀏覽器和服務器之間打開雙工、雙向通信會話。
WebSocket 構造函數,接受兩個參數,url 和 protocols(可選)。
url 以 ws://
或 wss://
(加密)開頭
protocols 是 單協議字符串或者包含協議字符串的數組。這些字符串用於指定子協議,這樣單個服務器能夠實現多個WebSocket子協議(例如,您可能但願一臺服務器可以根據指定的協議處理不一樣類型的交互)protocol)。若是不指定協議字符串,則假定爲空字符串。
var s = new WebSocket('ws://www.a.com/s.php') // 必須傳入絕對URL,能夠是任何網站
s.readyState // 0 創建鏈接 1 已經創建 2 正在關閉 3 鏈接已關閉或者沒有連接成功
s.send('hello') // 發送的數據必須是純文本
s.onopen = function (){
console.log('成功創建鏈接時觸發')
}
s.onerror = function () {
console.log('發生錯誤,鏈接不能持續時')
}
s.onmessage = function (event) { // 當接收到消息時
console.log(event.data) // 數據是純字符
}
s.close() // 關閉鏈接
s.onclose = function (event) {
/* * event.wasClean 是否明確的關閉 * event.code 服務器返回的數值狀態碼 * event.reason 字符串,服務器返回的消息 */
console.log('鏈接關閉時')
}
複製代碼
一共有 10 個屬性
binaryType
返回websocket鏈接所傳輸二進制數據的類型(blob, arraybuffer)bufferedAmount
只讀 返回已經被send()方法放入隊列中但尚未被髮送到網絡中的數據的字節數。一旦隊列中的全部數據被髮送至網絡,則該屬性值將被重置爲0。可是,若在發送過程當中鏈接被關閉,則屬性值不會重置爲0。extensions
只讀 返回服務器選擇的擴展名。這當前只是空字符串或鏈接協商的擴展列表onclose
用於指定鏈接失敗後的回調函數onmessage
用於指定當從服務器接受到信息時的回調函數onopen
用於指定鏈接成功後的回調函數protocol
只讀 服務器選擇的下屬協議readyState
只讀 當前的連接狀態url
只讀 WebSocket 的絕對路徑2 個方法
close(code, reason)
數字狀態碼 可選 默認 1005和一個可選的類可讀的字符串,它解釋了鏈接關閉的緣由。send(data)
向服務器發送數據(ArrayBuffer,Blob等)