fetch知識點彙總

来源:http://www.cnblogs.com/hzh-fe/archive/2017/12/02/7953717.html
-Advertisement-
Play Games

使用XHR發送一個json請求一般是這樣: 使用fetch的實例: Fetch參數 fetch(input [,init]) input(必須) 定義要獲取的資源(請求地址) init(可選) 參數 | 描述 method 請求使用的方法,如GET、POST headers http請求頭(user ...


使用XHR發送一個json請求一般是這樣:

 1 const xhr = new XMLHttpRequest()
 2 xhr.open('Get', url)
 3 xhr.responseType = 'json'
 4 
 5 xhr.onload = () => {
 6     console.log(xhr.response)      
 7 }
 8 
 9 xhr.onerror = () => {
10     console.log('error')
11 }
12 
13 xhr.send()

 

使用fetch的實例:

1 fetch(url).then(response => response.json())
2     .then(data => console.log(data))
3     .catch(e => console.log('error', e))

 

Fetch參數

fetch(input [,init])

 input(必須) 定義要獲取的資源(請求地址)

 init(可選)

 

參數 | 描述

method   請求使用的方法,如GET、POST

headers   http請求頭(user-Agent, Cookie)

body   請求的body信息

mode

fetch可以設置不同的模式使得請求有效. 模式可在fetch方法的第二個參數對象中定義.

可定義的模式如下:

  •  same-origin: 表示同域下可請求成功; 反之, 瀏覽器將拒絕發送本次fetch, 同時拋出錯誤 “TypeError: Failed to fetch(…)”.
  •  cors: 表示同域和帶有CORS響應頭的跨域下可請求成功. 其他請求將被拒絕.
  • cors-with-forced-preflight: 表示在發出請求前, 將執行preflight檢查.
  • no-cors: 常用於跨域請求不帶CORS響應頭場景, 此時響應類型為 “opaque”.

除此之外, 還有兩種不太常用的mode類型, 分別是 navigate , websocket , 它們是 HTML標準 中特殊的值, 這裡不做詳細介紹.

 credentials

 omit(預設值,預設為該值)、same-origin(同源,便是同域請求才發送cookie)、include(任何請求都帶cookie)

cache

  • default(表示fetch請求之前將檢查下http的緩存)
  • no-store(表示fetch請求將完全忽略http緩存的存在,這意味著請求之前將不再檢查下http的緩存, 拿到響應後, 它也不會更新http緩存)
  • no-cache(如果存在緩存,那麼fetch將發送一個條件查詢request和一個正常的request, 拿到響應後,它會更新http緩存)
  • reload(表示fetch請求之前將忽略http緩存的存在, 但是請求拿到響應後,它將主動更新http緩存)
  • force-cache(表示fetch請求不顧一切的依賴緩存, 即使緩存過期了,它依然從緩存中讀取. 除非沒有任何緩存, 那麼它將發送一個正常的request)
  • only-if-cached(表示fetch請求不顧一切的依賴緩存, 即使緩存過期了,它依然從緩存中讀取. 如果沒有緩存, 它將拋出網路錯誤(該設置只在mode為”same-origin”時有效).

如果fetch請求的header里包含 If-Modified-Since, If-None-Match, If-Unmodified-Since, If-Match, 或者 If-Range 之一, 且cache的值為 default , 那麼fetch將自動把 cache的值設置為 "no-store"

 

 Fetch - response type

 一個fetch請求的相應類型(response.type)為如下三種之一:

  • baisc (同域下,相應類型為basic)
  • cors (同樣是跨域下, 如果伺服器返回了CORS響應頭, 那麼響應類型將為 “cors”. 此時響應頭中除 Cache-Control , Content-Language , Content-Type , Expores , Last-Modified 和 Progma 之外的欄位都不可見.)
  • opaque ( 跨域下, 伺服器沒有返回CORS響應頭, 響應類型為 “opaque”. 此時我們幾乎不能查看任何有價值的信息, 比如不能查看response, status, url等等等等.)

註意: 無論是同域還是跨域, 以上 fetch 請求都到達了伺服器.

 

 Fetch 常見坑

  1.Fetch 請求預設是不帶 cookie 的,需要設置 fetch(url, {credentials: 'include'})

    預設情況下, fetch 不會從服務端發送或接收任何 cookies, 如果站點依賴於維護一個用戶會話,則導致未經認證的請求(要發送 cookies,必鬚髮送憑據頭)

  2.伺服器返回 400,500 錯誤碼時並不會 reject,只有網路錯誤這些導致請求不能完成時,fetch 才會被 reject。

    當接收到一個代表錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記為 reject, 即使該 HTTP 響應的狀態碼是 404 或 500。相反,它會將 Promise 狀態標記為 resolve (但是會將 reolve 的返回值的 ok 屬性設置為 false, 想要精確判斷fetch()是否成功,需要包含 promise resolved 的情況,此時再判斷 Response.ok 是不是為 true。HTTP狀態碼為200-299是才會設置為true), 僅當網路故障時或請求被阻止時,才會標記為 rejec

 

使用Fetch封裝request方法

http.js

  1 import 'whatwg-fetch';
  2 
  3 const netErrorStatu = 1;    // 網路錯誤
  4 const serverErrorStatu = 2;    // 伺服器錯誤
  5 const formatErrorStatu = 3;    // 數據格式錯誤
  6 const logicErrorStatu = 4;    // 業務邏輯錯誤
  7 
  8 const errorMsg = {
  9     [netErrorStatu]: '網路錯誤',
 10     [serverErrorStatu]: '伺服器錯誤',
 11     [formatErrorStatu]: '數據格式錯誤',
 12     [logicErrorStatu]: '業務邏輯錯誤'
 13 };
 14 
 15 class CustomFetchError {
 16     constructor(errno, data) {
 17         this.errno = errno;
 18         this.msg = errorMsg[errno];
 19         this.data = data;
 20     }
 21 }
 22 
 23 export function buildQuery(data) {
 24     const toString = Object.prototype.toString;
 25 
 26     const res = Object.entries(data).reduce((pre, [key, value]) => {
 27         let newValue;
 28 
 29         if (Array.isArray(value) || toString.call(value) === '[object Object]') {
 30             newValue = JSON.stringify(value);
 31         } else {
 32             newValue = (value === null || value === undefined) ? '' : value;
 33         }
 34 
 35         pre.push(`${key}=${encodeURIComponent(newValue)}`);
 36 
 37         return pre;
 38     }, []);
 39 
 40     return res.join('&');
 41 }
 42 
 43 export async function request(input, opt) {
 44     // 設置請求預設帶cookie
 45     const init = Object.assign({
 46         credentials: 'include'
 47     }, opt);
 48 
 49     let res;
 50     // 僅當網路故障時或請求被阻止時,才會標記為 rejec
 51     try {
 52         res = await fetch(input, init);
 53     } catch (e) {
 54         throw new CustomFetchError(netErrorStatu, e);
 55     }
 56     // 僅HTTP狀態碼為200-299是才會設置為true
 57     if (!res.ok) {
 58         throw new CustomFetchError(serverErrorStatu, res);
 59     }
 60 
 61     let data;
 62     // fetch()請求返回的response是Stream對象,調用response.json時由於非同步讀取流對象所以返回的是一個Promise對象    
 63     try {
 64         data = await res.json();
 65     } catch (e) {
 66         throw new CustomFetchError(formatErrorStatu, e);
 67     }
 68     // 根據和後臺的約定設置的錯誤處理
 69     if (!data || data.errno !== 0) {
 70         throw new CustomFetchError(logicErrorStatu, data);
 71     }
 72 
 73     return data.data;
 74 }
 75 
 76 export function get(url, params = {}, opt = {}) {
 77     const init = Object.assign({
 78         method: 'GET'
 79     }, opt);
 80 
 81     // ajax cache
 82     Object.assign(params, {
 83         timestamp: new Date().getTime()
 84     });
 85 
 86     const paramsStr = buildQuery(params);
 87 
 88     const urlWithQuery = url + (paramsStr ? `?${paramsStr}` : '');
 89 
 90     return request(urlWithQuery, init);
 91 }
 92 
 93 export function post(url, params = {}, opt = {}) {
 94     const headers = {
 95         'Content-Type': 'application/x-www-form-urlencoded'
 96     };
 97 
 98     const init = Object.assign({
 99         method: 'POST',
100         body: buildQuery(params),
101         headers
102     }, opt);
103 
104     return request(url, init);
105 }
106 
107 export default {
108     request,
109     get,
110     post
111 };

 

requset.js

 1 import { notification } from 'antd';
 2 import Loading from 'components/Loading';
 3 import { LOGIN_URL } from 'constants/basic';
 4 import * as http from './http';
 5 
 6 const loading = Loading.newInstance();
 7 
 8 async function request(method, url, params, opt = {}, httpOpt) {
 9     /**
10      * needLoading 是否添加loading圖片
11      * checkAccount 驗證未登陸是否跳登陸頁面
12      * showErrorMsg 是都顯示通用錯誤提示
13      */
14     const {
15         needLoading = true,
16         checkAccount = true,
17         showErrorMsg = true
18     } = opt;
19 
20     if (needLoading) {
21         loading.add();
22     }
23 
24     let res;
25 
26     try {
27         res = await http[method](url, params, httpOpt);
28     } catch (e) {
29         if (checkAccount && e.errno === 4 && e.data.errno === 10000) {
30             location.href = LOGIN_URL;
31         }
32 
33         if (showErrorMsg) {
34             notification.error({
35                 message: '提示信息',
36                 description: e.errno === 4 ? e.data.msg : e.msg
37             });
38         }
39 
40         throw e;
41     } finally {
42         if (needLoading) {
43             loading.remove();
44         }
45     }
46 
47     return res;
48 }
49 
50 export function get(...arg) {
51     return request('get', ...arg);
52 }
53 
54 export function post(...arg) {
55     return request('post', ...arg);
56 }

 

  github的代碼地址: https://github.com/haozhaohang/library


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 很多情況下,你會使用 CSS 庫,這些庫可能會意外覆蓋掉你自己的 CSS。所以當你需要確保某元素具有指定的 CSS 時,你可以使用 !important。 Hello World!是粉色的 ...
  • 1、js的簡介 (1)js是什麼? js是可以嵌入到html中,是基於對象和事件驅動的腳本語言。 特點: 交互性 安全性:js不能訪問本地磁碟 跨平臺:瀏覽器中都具備js解析器 (2)js能做什麼 js能動態的修改(增刪)html和css的代碼 能動態的校驗數據 (3)js的歷史及組成 BOM(瀏覽 ...
  • 內容為整理博主文章: "https://juejin.im/user/58870f04128fe10065efc8d9/article" 個人覺得他對Operators的解說較容易理解和全面,顧把它們整理在一起,也方面查找。 Operators: Observable 的 Operators 是實例 ...
  • s中的this總是讓人,是js眾所周知的坑之一。 總結一下,this的坑分為5種。 1.全局代碼中的this。 alert(this);//window 全局範圍內this將會全局,在瀏覽器window 2.作為單純函數調用 這裡this指向全局對象,就是window。在嚴格模式中,則undefie ...
  • 一般認為:嚴格模式下this不允許指向全局對象。 如:http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html 需要說明的是:本身指向全局的this是沒有問題的。 示例代碼: 控制台輸出為window對象(全局對象): 嚴格 ...
  • 查找基本分類如下: 1. 線性表的查找 順序查找 折半查找 分塊查找 2. 樹表的查找 二叉排序樹 平衡二叉樹 B樹 B+樹 3. 散列表的查找 今天介紹 二叉排序樹 。 二叉排序樹 ( Binary Sort Tree ) 又稱為 二叉查找樹 ,它是一種對排序和查找都很有用的特殊二叉樹。 1. 二 ...
  • 常用無返回值的事件 onabort圖像載入被中斷 onblur 元素失去焦點 onfocus 元素獲得焦點 onreset 重置按鈕被點擊 onselect 文本被選中 onsubmit 確認按鈕被點擊 onchange 域的內用被改變 onclick 當用戶點擊某個對象時調用的事件 ondblcl ...
  • 今天在寫代碼的時候,我犯了一個很low的錯誤,廢話不多說,直接上代碼: 大家看到之後,第一反應肯定會認為是個語法錯誤,可是自己仔細想想,這是什麼原因?似乎還不能解釋清楚,好奇寶寶模式立即啟動,經過查閱相關資料得到了答案,接下來我們一起來探討下其中的原理。 疑惑解答 大家有沒有考慮過為什麼上面這種寫法 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...