日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用 Fetch

發布時間:2025/5/22 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 Fetch 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文?https://www.cnblogs.com/libin-1/p/6853677.html

?

無論用JavaScript發送或獲取信息,我們都會用到Ajax。Ajax不需要刷新頁面就能發送和獲取信息,能使網頁實現異步更新。

幾年前,初始化Ajax一般使用jQuery的ajax方法:

$.ajax('some-url', {success: (data) => { /* do something with the data */ }, error: (err) => { /* do something when an error happens */} });

也可以不用jQuery,但不得不使用XMLHttpRequest,然而這是相當復雜

幸虧,瀏覽器現在支持Fetch API,可以無須其他庫就能實現Ajax

瀏覽器支持

桌面瀏覽器

?

?

手機/平板電腦

?

?

所有主要的瀏覽器(除了Opera Mini和老的IE)都支持Fetch。針對不支持的,可以使用Fetch polyfill

Fetch獲取數據

使用Fetch獲取數據很容易。只需要Fetch你想獲取資源。

假設我們想通過GitHub獲取一個倉庫,我們可以像下面這樣使用:

fetch('https://api.github.com/users/chriscoyier/repos');

Fetch會返回Promise,所以在獲取資源后,可以使用.then方法做你想做的。

fetch('https://api.github.com/users/chriscoyier/repos').then(response => {/* do something */})

如果這是你第一次遇見Fetch,也許驚訝于Fetch返回的response。如果console.log返回的response,會得到下列信息:

{body: ReadableStreambodyUsed: falseheaders: Headersok : true redirected : false status : 200 statusText : "OK" type : "cors" url : "http://some-website.com/some-url" __proto__ : Response }

可以看出Fetch返回的響應能告知請求的狀態。從上面例子看出請求是成功的(ok是true,status是200),但是我們想獲取的倉庫名卻不在這里。

顯然,我們從GitHub請求的資源都存儲在body中,作為一種可讀的流。所以需要調用一個恰當方法將可讀流轉換為我們可以使用的數據。

Github返回的響應是JSON格式的,所以調用response.json方法來轉換數據。

還有其他方法來處理不同類型的響應。如果請求一個XML格式文件,則調用response.text。如果請求圖片,使用response.blob方法。

所有這些方法(response.json等等)返回另一個Promise,所以可以調用.then方法處理我們轉換后的數據。

fetch('https://api.github.com/users/chriscoyier/repos').then(response => response.json()) .then(data => { // data就是我們請求的repos console.log(data) });

可以看出Fetch獲取數據方法簡短并且簡單。

接下來,讓我們看看如何使用Fetch發送數據。

Fetch發送數據

使用Fetch發送也很簡單,只需要配置三個參數。

fetch('some-url', options);

第一個參數是設置請求方法(如post、put或del),Fetch會自動設置方法為get。

第二個參數是設置頭部。因為一般使用JSON數據格式,所以設置ContentType為application/json。

第三個參數是設置包含JSON內容的主體。因為JSON內容是必須的,所以當設置主體時會調用JSON.stringify。

實踐中,post請求會像下面這樣:

let content = {some: 'content'}; // The actual fetch request fetch('some-url', { method: 'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(content) }) // .then()...

Fetch處理異常

雖然希望Ajax響應成功,但是仍會有問題出現:

  • 可能嘗試獲取不存在的資源
  • 沒有權限獲取資源
  • 輸入參數有誤
  • 服務器拋出異常
  • 服務器超時
  • 服務器崩潰
  • API更改
  • ...
  • 假設我們試圖獲取不存在錯誤,并了解如何處理錯誤。下面的例子我將chriscoyier拼錯為chrissycoyier

    // 獲取chrissycoyier's repos 而不是 chriscoyier's repos fetch('https://api.github.com/users/chrissycoyier/repos')

    為了處理此錯誤,我們需要使用catch方法。

    也許我們會用下面這種方法:

    fetch('https://api.github.com/users/chrissycoyier/repos').then(response => response.json()) .then(data => console.log('data is', data)) .catch(error => console.log('error is', error));

    然而卻得到下面這樣結果:


    獲取失敗,但是第二個.then方法會執行。

    ?

    如果console.log此次響應,會看出不同:

    {body: ReadableStreambodyUsed: trueheaders: Headersok: false // Response is not ok redirected: false status: 404 // HTTP status is 404. statusText: "Not Found" // Request not found type: "cors" url: "https://api.github.com/users/chrissycoyier/repos" }

    大部分是一樣的,只有ok、status和statusText是不同的,正如所料,GitHub上沒有發現chrissycoyier。

    上面響應告訴我們Fetch不會關心AJAX是否成功,他只關心從服務器發送請求和接收響應,如果響應失敗我們需要拋出異常。

    因此,初始的then方法需要被重寫,以至于如果響應成功會調用response.json。最簡單方法是檢查response是否為ok。

    fetch('some-url').then(response => { if (response.ok) { return response.json() } else { // Find some way to get to execute .catch() } });

    一旦我們知道請求是不成功的,我可以throw異常或rejectPromise來調用catch。

    // throwing an Error else {throw new Error('something went wrong!') } // rejecting a Promise else { return Promise.reject('something went wrong!') }

    這里選擇Promise.reject,是因為容易擴展。拋出異常方法也不錯,但是無法擴展,唯一益處在于便于棧跟蹤。

    所以,到現在代碼應該是這樣的:

    fetch('https://api.github.com/users/chrissycoyier/repos').then(response => { if (response.ok) { return response.json() } else { return Promise.reject('something went wrong!') } }) .then(data => console.log('data is', data)) .catch(error => console.log('error is', error));

    ?


    這樣錯誤就會進入catch語句中。

    ?

    但是rejectPromise時,只輸出字符串不太好。這樣不清楚哪里出錯了,你肯定也不會想在異常時,輸出下面這樣:

    ?

    讓我們在看看響應:

    {body: ReadableStreambodyUsed: trueheaders: Headersok: false // Response is not ok redirected: false status: 404 // HTTP status is 404. statusText: "Not Found" // Request not found type: "cors" url: "https://api.github.com/users/chrissycoyier/repos" }

    在這個例子中,我們知道資源是不存在。所以我們可以返回404狀態或Not Found原因短語,然而我們就知道如何處理。

    為了在.catch中獲取status或statusText,我們可以reject一個JavaScript對象:

    fetch('some-url').then(response => { if (response.ok) { return response.json() } else { return Promise.reject({ status: response.status, statusText: response.statusText }) } }) .catch(error => { if (error.status === 404) { // do something about 404 } })

    上面的錯誤處理方法對于下面這些不需要解釋的HTTP狀態很適用。

    • 401: Unauthorized
    • 404: Not found
    • 408: Connection timeout
    • ...

    但對于下面這些特定的錯誤不適用:

    • 400:Bad request
      例如,如果請求錯誤缺少必要的參數,就會返回400.

      光在catch中告訴狀態及原因短語并不足夠。我們需要知道缺少什么參數。
      所以服務器需要返回一個對象,告訴造成錯誤請求原因。如果使用Node和Express,會返回像下面這樣的響應:
    res.status(400).send({err: 'no first name' })

    無法在最初的.then方法中reject,因為錯誤對象需要response.json來解析。
    解決的方法是需要兩個then方法。這樣可以首先通過response.json讀取,然后決定怎么處理。

    fetch('some-error').then(handleResponse)function handleResponse(response) { return response.json() .then(json => { if (response.ok) { return json } else { return Promise.reject(json) } }) }

    首先我們調用response.json讀取服務器發來的JSON數據,response.json返回Promise,所以可以鏈式調用.then方法。

    在第一個.then中調用第二個.then,因為我們仍希望通過repsonse.ok判斷響應是否成功。

    如果想發送狀態和原因短語,可以使用Object.assign()將二者結合為一個對象。

    let error = Object.assign({}, json, {status: response.status, statusText: response.statusText }) return Promise.reject(error)

    可以使用這樣新的handleResponse函數,讓數據能自動的進入.then和.catch中。

    fetch('some-url').then(handleResponse).then(data => console.log(data)) .catch(error => console.log(error))

    處理其他響應類型

    到現在,我們只處理JSON格式的響應,而返回JSON格式數據大約占90%。

    至于其他的10%呢?

    假設上面的例子返回的是XML格式的響應,也許會收到下面異常:

    ?

    這是因為XML格式不是JSON格式,我們無法使用response.json,事實上,我們需要response.text,所以我們需要通過判斷響應的頭部來決定內容格式:

    .then(response => {let contentType = response.headers.get('content-type') if (contentType.includes('application/json')) { return response.json() // ... } else if (contentType.includes('text/html')) { return response.text() // ... } else { // Handle other responses accordingly... } });

    當我遇見這種問題時,我嘗試使用ExpressJWT處理身份驗證,我不知道可以發生JSON響應數據,所以我將XML格式設為默認。

    這是我們到現在完整代碼:

    fetch('some-url').then(handleResponse).then(data => console.log(data)) .then(error => console.log(error)) function handleResponse (response) { let contentType = response.headers.get('content-type') if (contentType.includes('application/json')) { return handleJSONResponse(response) } else if (contentType.includes('text/html')) { return handleTextResponse(response) } else { // Other response types as necessary. I haven't found a need for them yet though. throw new Error(`Sorry, content-type ${contentType} not supported`) } } function handleJSONResponse (response) { return response.json() .then(json => { if (response.ok) { return json } else { return Promise.reject(Object.assign({}, json, { status: response.status, statusText: response.statusText })) } }) } function handleTextResponse (response) { return response.text() .then(text => { if (response.ok) { return json } else { return Promise.reject({ status: response.status, statusText: response.statusText, err: text }) } }) }

    介紹zlFetch

    zlFetch庫就是上例中handleResponse函數,所以可以不用生成此函數,不需要擔心響應來處理數據和錯誤。

    典型的zlfetch像下面這樣:

    zlFetch('some-url', options).then(data => console.log(data)) .catch(error => console.log(error));

    使用之前,需要安裝zlFetch

    npm install zl-fetch --save

    接著,需要引入到你的代碼中,如果你需要polyfill,確保加入zlFetch之前引入它。

    // Polyfills (if needed) require('isomorphic-fetch') // or whatwg-fetch or node-fetch if you prefer // ES6 Imports import zlFetch from 'zl-fetch'; // CommonJS Imports const zlFetch = require('zl-fetch');

    zlFetch還能無須轉換成JSON格式就能發送JSON數據。

    下面兩個函數做了同樣事情,zlFetch加入Content-type然后將內容轉換為JSON格式。

    let content = {some: 'content'} // Post request with fetch fetch('some-url', { method: 'post', headers: {'Content-Type': 'application/json'} body: JSON.stringify(content) }); // Post request with zlFetch zlFetch('some-url', { method: 'post', body: content });

    zlFetch處理身份認證也很容易。

    常用方法是在頭部加入Authorization,其值設為Bearer your-token-here。如果你需要增加token選項,zlFetch會幫你創建此域。

    所以,下面兩種代碼是一樣的:

    let token = 'someToken' zlFetch('some-url', { headers: { Authorization: `Bearer ${token}` } }); // Authentication with JSON Web Tokens with zlFetch zlFetch('some-url', {token});

    下面就是使用zlFetch來從GitHub上獲取repos:

    ?

    總結

    Fetch是很好的方法,能發送和接收數據。不需要在編寫XHR請求或依賴于jQuery。

    盡管Fetch很好,但是其錯誤處理不是很直接。在處理之前,需要讓錯誤信息進入到catch方法中。

    使用zlFetch庫,就不需要擔心錯誤處理了。

    轉載于:https://www.cnblogs.com/liujinyu/p/10939785.html

    總結

    以上是生活随笔為你收集整理的使用 Fetch的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 少妇人妻偷人精品一区二区 | 亚洲视频h| 中文在线观看视频 | 4hu最新网址 | 91精品成人 | 中文精品一区二区三区 | 肉色超薄丝袜脚交一区二区 | 在线观看免费成人 | 亚欧综合在线 | 国产又粗又猛又爽又黄 | 丰满人妻妇伦又伦精品国产 | 奇米影视亚洲 | 国产精品天美传媒沈樵 | 艳妇乳肉豪妇荡乳xxx | 日本中文视频 | 成人美女在线观看 | 国产精品xxx在线观看www | 日韩欧美一区二区区 | 亚洲av无码一区二区三区网站 | 国产激情综合五月久久 | 国产一区二区在 | 成人在线观看91 | 深爱激情av| 日少妇的逼 | 一级全黄少妇性色生活片 | 国产极品美女高潮无套嗷嗷叫酒店 | 永久av免费 | 毛片无码免费无码播放 | 丁香六月激情综合 | 七仙女欲春2一级裸体片 | 成人国产精品 | 成年人免费视频网站 | 91久久精品国产91久久性色tv | 在线网站av | 毛片在线免费观看网址 | 婷色| 李宗瑞91在线正在播放 | 福利视频一区二区三区 | 亚洲国产日韩欧美 | 国产一二三在线 | 波多野结衣丝袜 | 捆绑调教在线观看 | 欧美在线另类 | 国产性猛交xxxⅹ交酡全过程 | 黄色精品在线观看 | 美女隐私无遮挡网站 | 久久综合爱 | 国产黄色小说 | 婷婷五月情 | 日本午夜影院 | 久久91| 韩国三级bd高清中字2021 | 潘金莲黄色一级片 | 最近2019中文字幕大全第二页 | 日韩激情电影在线 | 中文字幕乱轮 | 在线一级视频 | www成人在线 | 欧美色图一区 | 三级特黄| 五月丁香综合激情六月久久 | 玩偶姐姐在线观看免费 | 日本黄色片在线播放 | 国产精品女同一区二区 | 99久久精品免费视频 | av尤物在线 | 97人人爽人人爽人人爽人人爽 | 国产视频1区2区3区 国产欧美一区二区精品性色99 | 91人人草| 国产精品欧美综合亚洲 | 欧美精品在线第一页 | 久久97久久97精品免视看 | 人成精品| 蜜桃视频在线观看污 | 草草在线观看视频 | 伊人黄| 日日综合网 | 精品国产18久久久久久二百 | 未满十八18禁止免费无码网站 | 欧美成人国产精品一区二区 | 91久久国产综合久久91精品网站 | 二级黄色录像 | 毛片网站有哪些 | 草久网| 亚洲v国产v| 国产亚洲精久久久久久无码77777 | av中文字幕免费 | 影音先锋在线视频观看 | 情侣在线视频 | av中文字幕在线免费观看 | 91人人澡人人爽人人精品 | 色屁屁www| 日本少妇久久久 | 波多野av在线 | 日韩欧美在线中文字幕 | 久久欧洲 | 一区二区不卡视频 | 无码人妻丰满熟妇区96 | 蜜臀在线播放 |