1. 程式人生 > >使用 fetch 封裝網路請求,返回promise 物件

使用 fetch 封裝網路請求,返回promise 物件

1.fetch 的概念和用法

fetch 提供了對 Request 和 Response (以及其他與網路請求有關的)物件的通用定義。使之今後可以被使用到更多地應用場景中:無論是service workers、Cache API、又或者是其他處理請求和響應的方式,甚至是任何一種需要你自己在程式中生成響應的方式。

它還提供了一種定義,將 CORS 和 HTTP 原生的頭資訊結合起來,取代了原來那種分離的定義。

傳送請求或者獲取資源,需要使用 GlobalFetch.fetch 方法。它在很多介面中都被實現了,比如 

Window 和 WorkerGlobalScope。所以在各種環境中都可以用這個方法獲取到資源。

 fetch() 必須接受一個引數——資源的路徑。無論請求成功與否,它都返回一個 promise 物件,resolve 對應請求的 Response。你也可以傳一個可選的第二個引數init(參見 Request)。

一旦 Response 被返回,就有一些方法可以使用了,比如定義內容或者處理方法(參見 Body)。

你也可以通過 Request() 和 Response()

 的建構函式直接建立請求和響應,但是我們不建議這麼做。他們應該被用於建立其他 API 的結果(比如,service workers 中的 FetchEvent.respondWith)。

 2.語法

Promise<Response> fetch(input[, init]);

 

 引數:

?input 定義要獲取的指定資源,可以是字串也可以是Request物件

const myRequest = new Request('http://localhost/flowers.jpg');

const myURL 
= myRequest.url; // http://localhost/flowers.jpg const myMethod = myRequest.method; // GET const myCred = myRequest.credentials; // omit

fetch(myRequest)
  .then(response => response.blob()) .then(blob => { myImage.src = URL.createObjectURL(blob); });/pre>
 

 

init 可選一個配置項物件,包括所有對請求的設定。可選的引數有:

  • method: 請求使用的方法,如 GETPOST、put/delete/option/...
  • headers: 請求的頭資訊,形式為 Headers 的物件或包含 ByteString 值的物件字面量。
  • body: 請求的 body 資訊:可能是一個 BlobBufferSourceFormDataURLSearchParams 或者 USVString 物件。注意 GET 或 HEAD 方法的請求不能包含 body 資訊。
  • mode: 請求的模式,如 cors、 no-cors 或者 same-origin。
  • credentials: 請求的 credentials,如 omitsame-origin 或者 include。為了在當前域名內自動傳送 cookie , 必須提供這個選項, 從 Chrome 50 開始, 這個屬性也可以接受 FederatedCredential 例項或是一個 PasswordCredential 例項。
  • cache:  請求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
  • redirect: 可用的 redirect 模式: follow (自動重定向), error (如果產生重定向將自動終止並且丟擲一個錯誤), 或者 manual (手動處理重定向). 在Chrome中,Chrome 47之前的預設值是 follow,從 Chrome 47開始是 manual。
  • referrer: 一個 USVString 可以是 no-referrerclient或一個 URL。預設是 client。
  • referrerPolicy: Specifies the value of the referer HTTP header. May be one of no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。
  • integrity: 包括請求的  subresource integrity 值 ( 例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。

返回值:

一個 Promise,resolve 時回傳 Response 物件。

錯誤:

型別 描述
AbortError The request was aborted (using AbortController.abort()).
TypeError Since Firefox 43fetch() will throw a TypeError if the URL has credentials, such as http://user:[email protected].

 

跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器  讓執行在一個 origin (domain) 上的Web應用被准許訪問來自不同源伺服器上的指定的資源。當一個資源從與該資源本身所在的伺服器不同的域或埠請求一個資源時,資源會發起一個跨域 HTTP 請求

 

 

下面是使用Promise 封裝了Fetch 並返回promise 物件

 

const headers = new Headers({
  'Accept': 'application/json',
  'Content-Type': 'application/json'
});

function get (url) {
  return fetch(url, {
    method: 'GET',
    headers: headers
  }).then(response => {
    return handleResponse(url, response);
  }).catch(err => {
    console.error(`Request failed. Url = ${url} . Message = ${err}`);
    return {error: {message: 'Request failed.'}};
  })
}

function post (url, data) {
  return fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data)
  }).then(response => {
    return handleResponse(url, response);
  }).catch(err => {
    console.error(`Request failed. Url = ${url} . Message = ${err}`);
    return {error: {message: 'Request failed.'}};
  })
}

function put (url, data) {
  return fetch(url, {
    method: 'PUT',
    headers: headers,
    body: JSON.stringify(data)
  }).then(response => {
    return handleResponse(url, response);
  }).catch(err => {
    console.error(`Request failed. Url = ${url} . Message = ${err}`);
    return {error: {message: 'Request failed.'}};
  })
}

function handleResponse (url, response) {
  if (response.status < 500) {
    return response.json();
  } else {
    console.error(`Request failed. Url = ${url} . Message = ${response.statusText}`);
    return {error: {message: 'Request failed due to server error '}};
  }
}

export {get, post, put}