異步請求fetch之初體驗


更好閱讀體驗可移步我的博客:Blog

導讀

傳遞信息到服務器,從服務器獲取信息,是前端發展的重中之重,尤其是現在前后端分離的大前提下,前后端的數據交互是前端的必修科目了。從很久之前到現在,ajax都是每個前端入行者必須技能。當然為了便於開發者, 各種三方工具將ajax包裝,然后給開發者使用,jquery、axios等等。這都不是今天的重點, 今天要說一個JavaScript原生的獲取資源接口 Fetch API, 雖然各大瀏覽器支持率不高,但是這樣的一個概念確實值得了解學習,並且現在我們可以通過polyfill來實現不同瀏覽器的兼容性問題

Fetch

先來看看各個瀏覽器對fetch的原生支持情況,可以看到支持性並不是很高,safari在10.1 之后才支持,ios更是10.3之后才支持,IE完全不支持。當然新技術的發展總會經歷這個過程。不過,想提前嘗嘗鮮也是可以的我們可以使用 polyfill

Fetch原生支持

聲明:以下的所有代碼測試都是基於 Chrome 實現

廢話不多說,

fetch 返回的是一個Promise,我們先來看一個基本的 fetch 結構

fetch(url, option).then( res => {
    //do something
}).catch(err => {
    //do something
})

fetch 的url 參數是必須的,option參數可選
以上就是整個的請求以及處理過程, 驚不驚喜,意不意外,沒錯就是這么簡單清晰明了,沒有原生ajax的那些 XMLHttpRequest bulabula 一大堆。也不需要再額外引入一個jquery包(當然項目中使用到的話除外)。當然因為fetch的返回值是一個Promise, 不需要再去使用回調函數從而有效避免回調地獄。

當然,fetch不止於此,我們的需求也不止於此,我們可能需要post請求,可能需要跨域請求,控制從服務器獲取的信息的格式(json、string、blob等),此時,便需要設置參數信息,對返回信息進行處理。

option

來看看fetch的可選參數option的可選值,fetch默認是get方法,也可以在option中設置為其他方法

  • method:get | post 等方法
  • headers:任何你想加到請求中的頭,可以是對象字面量的方式也可以是通過 Headers
  • body:發送給服務器的信息, 可以是JSON, ufferSource, FormData, URLSearchParams, 或 USVString。注意get和HEAD請求沒有body
  • mode:請求模式, 可選值為 cors, no-cors, same-origin, 或 navigate,cors-with-forced-preflight。默認值應該為 cors。但在Chrome中,Chrome 47 之前的版本默認值為 no-cors ,自Chrome 47起,默認值為same-origin。--MDN Request
  • credentials:在請求中是否需要憑據。在請求數據中根據是否需要攜帶Cookie 來設置其值,可選值為omit(在請求中不懈怠認證憑據(Cookie)), same-origin(在同原站點下包含憑據), 或 include(對所有網站包含認證憑據)
  • cache:如何處理緩存,可取值有 default | no-store | no-cache | reload | force-cache | only-if-cached
  • redirect:對重定向的處理,可取值 follow, error, redirect
  • referrer:一個指定了no-referrer, client, 或一個 URL的 USVString 。默認值是client.
  • integrity: 包括請求的 subresource integrity 值 (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).

mode

mode 參數便於 CORS, 設置不同的值可以使在不同的請求方式下,使得請求有效。

  • cors:在同域和帶有CORS響應頭的跨域下可以請求成功
  • no-cors:常用於在跨域不帶CORS場景下, 此時請求發出並且會有響應,但是此時type為“opaque”, status為0 ,js獲取不到返回數據。
  • same-origin:在同域下請求
  • cors-with-forced-preflight:在請求前進行preflight 檢查
fetch("https://api.github.com/users/mzabriskie", {mode: "no-cors"}).then(response => {
	return response;
}).then(function(data) {
	console.log(data);
}).catch(function(e) {
	console.log("Oops, error");
});

執行以上代碼返回

no-cors返回值信息

fetch("https://api.github.com/users/mzabriskie", {mode: "cors"}).then(response => {
	return response;
}).then(function(data) {
	console.log(data);
}).catch(function(e) {
	console.log("Oops, error");
});

以上代碼返回

cors返回值

headers

該參數的值可以為對象字面量

headers: {
    "Content-Type": "application/json"
}

也可以創建 Headers 對象,通過append() 和delete() 等方法對其進行操作,

var headers = new Headers();
headers.append( "Content-Type", "application/json");
fetch(url, {
    method: post,
	headers: headers,
	body: {
	    name: "jack"
	}
})

Request

Fetch 提供了對 Request 和 Response (以及其他與網絡請求有關的)對象的通用定義。所以在一個Fetch請求中,完全可以只使用Request 和 Response兩個對象,通過Request 設置參數,通過Response 對返回值進行處理。
一個Fetch還可以寫成以下形式

var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');

var option = { method: 'GET',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' };

var myRequest = new Request('https://api.github.com/users/mzabriskie',option);

fetch(myRequest).then(function(response) {
    ... 
});

參數設置如 option 下介紹

Response

Fetch API 的Response接口呈現了對一次請求的響應數據

其包含一次請求的響應信息,響應狀態等。
包含的一些常用屬性(只讀)

  • url:包含請求地址url
  • status:響應狀態碼(200成功)
  • ok:一個布爾值標識請求成功或失敗
  • statusText:包含與狀態碼對應的狀態信息
  • headers:包含於請求關聯的Headers對象

方法

  • clone(): 創建Response對象的克隆

Response可以使用以下方法,對響應數據進行處理

arrayBuffer()、blob()、formData()、json()、text()等
以下為使用json() 方法返回的數據信息

fetch("https://api.github.com/users/mzabriskie", {mode: "no-cors"}).then(response => {
	return response.json();
}).then(function(data) {
	console.log(data);
}).catch(function(e) {
	console.log("Oops, error");
});

cors json()返回值

檢測請求是否成功

同XMLHttpResponse一樣,請求發出,服務器發出返回碼,除了407以外,其不會進入錯誤捕捉。也就是說除了網絡故障或者跨域請求被拒絕等請求失敗的情況,fetch() 的Promise是不會 reject的,所以為了請求能按照我們的預期實現,我們必須加一個判斷,判斷請求是否成功並返回了我們想要的數據。我們當然可以像 XMLHttpResponse 一樣對響應的狀態碼進行判斷,不過我們還有選擇,對response.ok 這個布爾值入手。
細心的同學可能從之前的截圖中看到,在請求成功和失敗的情況下,屬性 ok 的值 分別為true 和false 這里就不贅余天價截圖了,上代碼

fetch("https://api.github.com/users/mzabriskie", {mode: "cors"}).then(response => {
	if(response.ok) {
	    response.json().then(data => {
	        console.log(data);
	    });
	} else {
	    console.log("請求不成功,狀態碼為", response.status);
	}
}).catch(function(e) {
	console.log("Oops, error");
});

致此, 一個 fetch 的簡單請求便完成了,但是fetch功能遠不止這些

fetch 與 ES7的async/await 搭配使用等等,路很長一步一腳印

參考鏈接

Fetch API - Web API 接口 | MDN
Request - Web API 接口 | MDN
Headers - Web API 接口 | MDN
Response - Web API 接口 | MDN
Body - Web APIs | MDN


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM