fetch是一種使用 promise 爲構建塊的現代異步網絡請求方法javascript
1998年發佈的IE5,讓咱們可以使用 XMLHttpRequest (XHR) 對象在瀏覽器中進行異步網絡請求。 在此後的幾年,GMail 和其餘豐富的應用程序大量使用它,並使該方法如此受迎,以致於它必須有一個名稱:AJAX。 直接使用 XMLHttpRequest 一直很痛苦,因此它常常被一些庫抽象集成,比較有表明性的好比說 jQuery 使用 XHR 封裝了本身的輔助函數,好比:html
這些方法對更方便的使用 XHR 發送異步請求有很大的影響,特別是它們也確保了在舊瀏覽器上也可以正常工做。Fetch,是當今進行異步網絡請求的新標準,而且使用了 Promise 做爲構建塊,除了 IE 以外,Fetch 在各主要瀏覽器中都可以獲得很好的支持。 java
使用 Fetch 方法發起 GET 請求是很是簡單的:ios
fetch('/file.json')
複製代碼
當你已經開始使用它:fetch
將會向相同的域名發起一個 HTTP 請求以得到域名下 file.json 資源。 如您看見的那樣,fetch 方法可在全局 window
做用域下得到,如今咱們讓它變得更有意義,它在實際狀況下的使用下多是這樣的:git
fetch('./file.json')
.then(response => response.json())
.then(data => console.log(data))
複製代碼
調用 fetch()
會返回一個 promise 對象,咱們能夠等待這個 promise 對象 resolve 以後將返回的結果傳遞給 promise 對象的 then 方法。then 裏面的回調函數接收到的 fetch
Promise 返回的對象,即 Response 對象。在下面會詳細介紹這個 Response 對象。github
由於 fetch()
方法會返回一個 Promise 對象,咱們可使用 promise 對象的 catch
方法攔截在請求執行過程當中發生的任何錯誤,以及在 then
的回調函數中的處理結果:ajax
fetch('./file.json')
.then(response => {
//...
})
.catch(err => console.error(err))
複製代碼
另外一個捕獲請求發生錯誤的方法是在第一個 then
裏面對它進行處理json
fetch('./file.json')
.then(response => {
if (!response.ok) { throw Error(response.statusText) }
return response
})
.then(response => {
//...
})
複製代碼
調用 fetch()
返回的響應對象包含有關網絡請求和響應的全部信息。axios
經過訪問響應對象上的 headers
屬性使您可以查看請求返回的 HTTP 頭:api
fetch('./file.json').then(response => {
console.log(response.headers.get('Content-Type'))
console.log(response.headers.get('Date'))
})
複製代碼
此屬性是表示 HTTP 響應狀態的整數 ( 響應頭部的狀態碼 )。
fetch('./file.json').then(response => console.log(response.status))
複製代碼
statusText 是表示響應狀態消息的屬性。若是請求成功,則狀態爲OK。
fetch('./file.json').then(response => console.log(response.statusText))
複製代碼
url 是表示咱們請求資源的完整 URL 的屬性
fetch('./file.json').then(response => console.log(response.url))
複製代碼
能夠經過下面這些方法獲得響應主體的內容:
text()
將主體內容做爲字符串返回json()
將主體內容通過 JSON.parse 轉換後返回blob()
將主體內容做爲 Blob 對象返回formData()
將主體內容做爲 FormData 對象返回arrayBuffer()
將主體內容做爲 arrayBuffer 對象返回全部這些方法都會返回一個 Promise,好比說:
fetch('./file.json')
.then(response => response.text())
.then(body => console.log(body))
複製代碼
fetch('./file.json')
.then(response => response.json().catch(()=>({})))//響應狀態碼爲 200 但沒有響應主題內容的時候,使用json()方法會報錯,所以須要catch到這個錯誤
.then(body => console.log(body))
複製代碼
可使用 ES2017 的 async
方法對上面的方法進行改寫:
;(async () => {
const response = await fetch('./file.json')
const data = await response.json()
console.log(data)
})()
複製代碼
請求對象表示對資源的請求,一般能夠由 new Request()
方法生成。 好比說:
const req = new Request('/api/todos')
複製代碼
請求對象提供了一些只讀屬性來檢查請求的詳細信息,包括:
method
:請求的方法,包括:GET、POST、PUT、HEAD、DELETE 等等url
:請求的 URLheaders
:請求的關聯請求頭的對象referrer
:請求的引用者cache
:請求的緩存模式(好比說:default、reload、no-cache) 還公開了一些處理請求主體的方法:json()
、text()
、formData()
完整的 API 能夠在 Request 中找到。咱們常常須要可以設置 HTTP 請求頭部,fetch
使咱們可以用 Headers 對象執行此操做:
const headers = new Headers()
headers.append('Content-Type', 'application/json')
複製代碼
或者寫成👇這樣:
const headers = new Headers({
'Content-Type': 'application/json'
})
複製代碼
要使請求帶上請求頭,咱們將 Request
對象傳給 fetch()
而不是隻傳 URL。 相比於:
fetch('./file.json')
複製代碼
咱們這樣作:
const request = new Request('./file.json', {
headers: new Headers({
'Content-Type': 'application/json'
})
})
fetch(request)
複製代碼
Header
對象不只能夠設置鍵值對,咱們也能夠查詢其中的值:
headers.has('Content-Type')
headers.get('Content-Type')
複製代碼
而且,咱們也能夠刪除以前設置的請求頭:
headers.delete('X-My-Custom-Header')
複製代碼
Fetch 也容許在咱們的請求中使用其餘的 HTTP 請求方法,好比說:POST, PUT, DELETE 或者 OPTIONS。 在請求對象的 method 屬性中指定方法,並在請求頭和請求體中傳遞其他參數: POST 請求的例子:
const options = {
method: 'post',
headers: {
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: 'name=Flavio&test=1'
}
fetch(url, options).catch(err => {
console.error('Request failed', err)
})
複製代碼
在 fetch
被推出的這幾年,一旦使用 fetch
發起一個請求就沒有辦法終止這個請求,如今,咱們能夠經過引入通用 API: AbortController 和 AbortSignal 來通知停止事件。 您能夠將 signal 做爲 fetch 的參數傳遞給 fetch
:
const controller = new AbortController()
const signal = controller.signal
fetch('./file.json', { signal })
複製代碼
好比,您能夠設置一個定時器當 fetch
請求執行 5s 以後終止請求:
setTimeout(() => controller.abort(), 5 * 1000)
複製代碼
即便這個請求已經返回了,調用 abort()
也不會致使任何錯誤, 當停止信號發出後,fetch 將會由被叫作 AbortError
的 DOMException
對象(DOMException是W3C DOM核心對象。DOMException接口表示一個處理的錯誤,當一個操做不可能執行的時候,會拋出一個異常。例如試圖建立一個無效的DOM, 或經過一個不存在的節點做爲參數節點操做方法)reject 返回的 promise:
fetch('./file.json', { signal })
.then(response => response.text())
.then(text => console.log(text))
.catch(err => {
if (err.name === 'AbortError') {
console.error('Fetch aborted')
} else {
console.error('Another error', err)
}
})
複製代碼
網絡請求很是難,對嗎?您可能發現了當您須要一些基於 Fetch 構建的附加功能時, Axios 這個 JavaScript 庫更加符合您的需求,那如今就去學習吧!