日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

認(rèn)識(shí) Fetch API

 ws8637 2019-02-22

(給前端大全加星標(biāo),提升前端技能


英文:Flavio 譯文:眾成翻譯/涯丨角

https:///article/understanding-the-fetch-api

介紹 Fetch API

自從1998年發(fā)布IE5以來(lái),瀏覽器中異步網(wǎng)絡(luò)請(qǐng)求都是通過(guò) XMLHttpRequest (XHR)。

這之后幾年,Gmail等應(yīng)用大量使用這種方法,使這種方法逐漸流行,并給它一個(gè)名字:AJAX。

直接使用XMLHttpRequest總是非常痛苦的,許多庫(kù)都對(duì)這種方法進(jìn)行了封裝,特別地,jQuery封裝的方法如下:

  • jQuery.ajax()

  • jQuery.get()

  • jQuery.post()

這些方法內(nèi)部做了許多兼容性的處理,來(lái)使這些方法在那些較老版本的瀏覽器上仍能正常工作。

Fetch API 已經(jīng)作為現(xiàn)代瀏覽器中異步網(wǎng)絡(luò)請(qǐng)求的標(biāo)準(zhǔn)方法,其使用 Promise 作為基本構(gòu)造要素。

Fetch 在主流瀏覽器中都有很好的支持,除了IE。

GitHub 上有發(fā)布的polyfill https://github.com/github/fetch ,使fetch可以在任何瀏覽中使用。

使用Fetch

GET 請(qǐng)求中使用Fetch非常簡(jiǎn)單,如下:

fetch('/file.json')

上面這段代碼表示,fetch 創(chuàng)建了一個(gè) HTTP 請(qǐng)求,去本域下請(qǐng)求 file.json 資源。

正如你看到的,fetch函數(shù)可以在全局window作用域下使用。

現(xiàn)在,我們做些更有用的事,來(lái)看一看請(qǐng)求到的文件的內(nèi)容:

fetch('./file.json')

  .then(response => response.json())

  .then(data => console.log(data))

fetch() 會(huì)返回一個(gè) promise。然后我們用then()方法編寫處理函數(shù)來(lái)處理promise中異步返回的結(jié)果。

處理函數(shù)會(huì)接收f(shuō)etch promise的返回值,這是一個(gè) Response 對(duì)象。

我們會(huì)在下一部分看到這個(gè)對(duì)象的細(xì)節(jié)。

捕獲錯(cuò)誤

既然 fetch() 返回一個(gè)promise,我們可以用promise的catch來(lái)攔截在執(zhí)行這個(gè)請(qǐng)求和then里面回調(diào)函數(shù)中發(fā)生的任何錯(cuò)誤。

fetch('./file.json')

.then(response => {

  //...

})

.catch(err => console.error(err))

響應(yīng)對(duì)象

調(diào)用fetch()所返回的響應(yīng)對(duì)象包含了所有關(guān)于這個(gè)網(wǎng)絡(luò)請(qǐng)求的請(qǐng)求和響應(yīng)信息。

元數(shù)據(jù)

headers

HTTP請(qǐng)求的頭部信息可以通過(guò)訪問(wèn)響應(yīng)對(duì)象的headers屬性,如下所示:

fetch('./file.json').then(response => {

  console.log(response.headers.get('Content-Type'))

  console.log(response.headers.get('Date'))

})

status

這個(gè)屬性是一個(gè)整形數(shù)字,表示HTTP響應(yīng)狀態(tài)。

  • 101, 204, 205, 或 304 代表沒有響應(yīng)體的狀態(tài)

  • 200 到 299 代表請(qǐng)求成功的狀態(tài)

  • 301, 302, 303, 307, 或 308 代表重定向的狀態(tài)

fetch('./file.json').then(response => console.log(response.status))

statusText

statusText 屬性表示響應(yīng)狀態(tài)信息。如果請(qǐng)求成功,其值為'OK'。

fetch('./file.json').then(response => console.log(response.statusText))

url

url 表示我們請(qǐng)求資源的全路徑URL。

fetch('./file.json').then(response => console.log(response.url))

響應(yīng)體

響應(yīng)會(huì)有響應(yīng)體,可以通過(guò) text() 或者 json() 方法來(lái)拿到,這會(huì)返回一個(gè)promise對(duì)象。

fetch('./file.json')

  .then(response => response.text())

  .then(body => console.log(body))

fetch('./file.json')

  .then(response => response.json())

  .then(body => console.log(body))

相同的功能可以用 ES2017 async 函數(shù):

;(async () => {

  const response = await fetch('./file.json')

  const data = await response.json()

  console.log(data)

})()

請(qǐng)求對(duì)象

請(qǐng)求對(duì)象表示請(qǐng)求一個(gè)資源請(qǐng)求,它通常通過(guò) new Request() API創(chuàng)建。

例如:

const req = new Request('/api/todos')

請(qǐng)求對(duì)象提供了幾個(gè)只讀的屬性來(lái)檢查資源請(qǐng)求的細(xì)節(jié),包括

  • method: 請(qǐng)求方法 (GET, POST, 等)

  • url: 請(qǐng)求的URL

  • headers: 請(qǐng)求的頭部信息對(duì)象

  • referrer: 請(qǐng)求的網(wǎng)站來(lái)路

  • cache: 請(qǐng)求的緩存模式(例如:default, reload, no-cache).

并且提供了一些方法,如:json(), text() 和 formData() 來(lái) 處理請(qǐng)求體。

全部的API可以查看https://developer.mozilla.org/docs/Web/API/Request

請(qǐng)求頭

設(shè)置 HTTP 請(qǐng)求頭是一個(gè)基本的功能,fetch通過(guò)Headers對(duì)象來(lái)讓我們操作請(qǐng)求頭:

const headers = new Headers()

headers.append('Content-Type', 'application/json')

或者更簡(jiǎn)單可以這樣:

const headers = new Headers({

  'Content-Type': 'application/json'

})

為了把headers加到請(qǐng)求中,我們用Request對(duì)象,把它添加到fetch()函數(shù)的參數(shù)中,代替?zhèn)鱑RL參數(shù)。

代替下面的代碼:

fetch('./file.json')

我們這樣做

const request = new Request('./file.json', {

  headers: new Headers({

    'Content-Type': 'application/json'

  })

})

fetch(request)

Headers 對(duì)象沒有被限制設(shè)置值,我們也可以查詢它:

headers.has('Content-Type')

headers.get('Content-Type')

并且我們可以刪除之前設(shè)置的header:

headers.delete('X-My-Custom-Header')

POST請(qǐng)求

Fetch 也可以用其它的 HTTP 方法,如:POST, PUT, DELETE 或者 OPTIONS。

在method屬性中指定請(qǐng)求的方法,可以在請(qǐng)求頭和請(qǐng)求體中添加額外的參數(shù):

這是一個(gè)POST請(qǐng)求的例子:

const options = {

  method: 'post',

  headers: {

    'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8'

  },

  body: 'foo=bar&test=1'

}


fetch(url, options).catch(err => {

  console.error('Request failed', err)

})

Fetch 弊端

雖然fetch比XHR有極大的提高,特別是它在Service Worker中的集成,但是 Fetch 現(xiàn)在還 沒有方法中止一個(gè)請(qǐng)求 。而且用 Fetch 不能監(jiān)測(cè)上傳進(jìn)度。

如果在你的應(yīng)用中需要這些功能, Axios 庫(kù)可以是個(gè)不錯(cuò)的選擇。

如何取消fetch請(qǐng)求

在fetch剛出現(xiàn)的幾年,并沒有一個(gè)方法來(lái)取消已經(jīng)發(fā)出的請(qǐng)求。

現(xiàn)在我們可以這樣做了,多虧了AbortController 和 AbortSignal,這是個(gè)通用的API 來(lái)通知 中止 事件。

你可以通過(guò)添加一個(gè)signal參數(shù)來(lái)整合這些API:

const controller = new AbortController()

const signal = controller.signal


fetch('./file.json', { signal })

你可以設(shè)置一個(gè)超時(shí),在請(qǐng)求發(fā)出后5秒后,來(lái)取消請(qǐng)求:

setTimeout(() => controller.abort(), 5 * 1000)

很方便地,如果fetch已經(jīng)返回,調(diào)用abort()函數(shù)不會(huì)導(dǎo)致錯(cuò)誤。

當(dāng)取消信號(hào)發(fā)生,fetch會(huì)拋出一個(gè)DOMException,異常的name屬性值為'AbortError',可以在promise的catch中捕獲這個(gè)異常:

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)

    }

  })

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多