fetch:不同的xhr請求

fetch初識

此功能某些瀏覽器尚在開發中,請參考瀏覽器兼容性表格以獲得在不一樣瀏覽器中適合使用的前綴。因爲該功能對應的標準文檔可能被從新修訂,因此在將來版本的瀏覽器中該功能的語法和行爲可能隨之改變。html

Note: 若是不須要支持落後的IE系列瀏覽器,就能夠放心大膽的使用吧!
ps: 固然也可使用第三方的polyfill 庫!https://github.com/github/fetchnode

fetch提供了對於xhr的這種請求中的常見的【請求 Request】、【響應 Response】兩個對象的定義,就像node發起一個請求或者響應一個請求同樣,建立了request、response兩個實例對象,供使用者獲取整個請求過程當中的請求和響應信息。git

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

fetch() 必須接受一個參數——資源的路徑。不管請求成功與否,它都返回一個 promise 對象,resolve 對應請求的 Response。你也能夠傳一個可選的第二個參數—— init(參考 Request)。json

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

你也能夠經過 Request() 和 Response() 的構造函數直接建立請求和響應,可是咱們不建議這麼作。他們應該被用於建立其餘 API 的結果(好比,service workers 中的 FetchEvent.respondWith)。數組

fetch由來

參考:https://developer.mozilla.org...
https://developer.mozilla.org...
https://developer.mozilla.org...
在這裏可能須要先說下fetch方法的定義,其最原始的定義是在一個接口叫作GlobalFetch,該接口包含了GlobalFetch.fetch() 方法,Window 和WorkerGlobalScope都實現了GlobalFetch 接口,後來瀏覽器都把這個接口做了修改,造成了新的mixin,也就是WorkerOrGlobalScope,繼而演變爲:WindowOrWorkerGlobalScope,WindowOrWorkerGlobalScope混入【mixin】 了對 Window 和WorkerGlobalScope 接口的公共特性的描述【包括常見的setInterval、setTimeout等】。顯然除了下文即將列出的以外,這些接口中的每個,均可以增長更多的特性。promise

GlobalFetch =》 WorkerOrGlobalScope =》WindowOrWorkerGlobalScope瀏覽器

Note: WindowOrWorkerGlobalScope 是一個 mixin 而並不是 interface。不能建立一個類型爲 WindowOrWorkerGlobalScope 的對象。緩存

因爲 Window 和WorkerGlobalScope都實現了上述mixin,故而能夠放心的在全局域下使用fetch,

fetch概念

Fetch 是一個現代的概念, 等同於 XMLHttpRequest。它提供了許多與XMLHttpRequest相同的功能,但被設計成更具可擴展性和高效性。
Fetch 的核心在於對 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用於初始化異步請求的 global fetch。得益於 JavaScript 實現的這些抽象好的 HTTP 模塊,其餘接口可以很方便的使用這些功能。

Service Workers 是一個利用了 Fetch 實現的接口的例子。

除此以外,Fetch 還利用到了請求的異步特性——它是基於 Promise 的。

fettch使用

參考:https://developer.mozilla.org...
https://developer.mozilla.org...
這裏先給出一個很簡單的例子,以上代碼中,咱們經過網絡獲取了一個圖片,而後將它插入到一個 <img> 標籤中。這個最簡單的用法中,fetch() 接受了一個參數——請求的地址——而後返回一個包含 response(一個 Response 對象)的 promise 對象。:

var myImage = document.querySelector('img');

fetch('flowers.jpg')
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

這個例子很簡單,不過仍是須要先判斷下是否支持fetch:

if(self.fetch) {
    // run my fetch request here
} else {
    // do something with XMLHttpRequest?
}

上面簡單的例子已經包含了response對象、blob方法、then方法;後面一一簡述;上面的例子中,fetch函數只是使用了一個參數,也就是url,即獲取數據的後段地址,其實還有第二個參數 init對象;

var myHeaders = new Headers();

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

fetch('flowers.jpg',myInit)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

通過進一步的完善,fetch使用變成了這個樣子。實際上fetch的定義是這樣的:

Promise<Response> fetch(input[, init]);
//another to write the args of fetch 另外一種書寫方式
var myRequest = new Request(input, init);
Promise<Response> fetch(myRequest);

參數

參數的具體介紹:

參數
input
定義要獲取的資源。這多是:
一個 USVString 字符串,包含要獲取資源的 URL。一些瀏覽器會接受 blob: 和 data: 做爲 schemes.
一個 Request 對象。
init 可選
一個配置項對象,包括全部對請求的設置。可選的參數有:
method: 請求使用的方法,如 GET、POST。
headers: 請求的頭信息,形式爲 Headers 的對象或包含 ByteString 值的對象字面量。
body: 請求的 body 信息:多是一個 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 對象。注意 GET 或 HEAD 方法的請求不能包含 body 信息。
mode: 請求的模式,如 cors、 no-cors 或者 same-origin。
credentials: 請求的 credentials,如 omit、same-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-referrer、client或一個 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 對象。

Exceptions
Type    Description
TypeError    Since Firefox 43, fetch() will throw a TypeError if the URL has credentials, such as http://user:password@example.com.

以上能夠看到的就是全部的參數,一樣也是有兩種形式的書寫:

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
//它的內容能夠被獲取:
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue"); //http 頭部信息
var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };

fetch('flowers.jpg',myInit)
.then(function(response) {......
//或者使用這個來構建fetch參數,所需的參數和fetch所需的參數同樣
var anotherRequest = new Request(input,myInit);

其中的頭部有些須要注意,詳情查看:https://developer.mozilla.org... 能夠直接使用Headers構建新的請求頭,headers是由鍵值對構成,不過有的請求頭只容許用戶代理作修改,詳情參見:https://developer.mozilla.org...
同時Guard也是Headers中的重要部分,因爲 Headers 能夠在 request 請求中被髮送或者在 response 請求中被接收,而且規定了哪些參數是可寫的,Headers 對象有一個特殊的 guard 屬性。這個屬性沒有暴露給 Web,可是它影響到哪些內容能夠在 Headers 對象中被操做。

可能的值以下:

  • none:默認的

  • request:從 request 中得到的 headers(Request.headers)只讀【後端獲取http請求對象】

  • request-no-cors:從不一樣域(Request.mode no-cors)的 request 中得到的 headers 只讀

  • response:從 response 中得到的 headers(Response.headers)只讀

  • immutable:在 ServiceWorkers 中最經常使用的,全部的 headers 都只讀
    下面分別介紹request、body、response

request請求

瞭解了以上部分後,就知道能夠構建request來發起http請求,

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
//它的內容能夠被獲取:
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue"); //http 頭部信息

//屬性
Request.method 只讀
請求使用的方法 (GET, POST, 等.)
Request.url 只讀
請求使用的 URL。
Request.headers 只讀
請求所關聯的 Headers 對象。
Request.context 只讀  
請求的上下文 例如:(例如:audio, image, iframe, 等)
Request.referrer 只讀
請求的來源 (例如:client).
Request.mode 只讀
請求的模式 (例如: cors, no-cors, same-origin).
Request.credentials 只讀
請求的憑證 (例如: omit, same-origin).
Request.redirect 只讀
如何處理重定向模式 (例如: follow, error, or manual)
Request.integrity 只讀
請求內容的 subresource integrity 值 (例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
Request.cache 只讀
請求的緩存模式 (例如: default, reload, no-cache).
Request implements Body, so it also has the following property available to it:

Body.bodyUsed 只讀
指示body是否被使用, 類型爲Boolean

body請求正文

不論是請求仍是響應都可以包含body對象. body也能夠是如下任意類型的實例.

ArrayBuffer
ArrayBufferView (Uint8Array and friends)
Blob/File
string
URLSearchParams
FormData
Body 類定義瞭如下方法 (這些方法都被 Request 和Response所實現)以獲取body內容. 這些方法都會返回一個被解析後的promise對象和數據.

Body.bodyUsed 只讀
包含一個指示body是否被讀取過的 Boolean 值。
方法Edit

Body.arrayBuffer()
使用一個buffer數組來讀取 Response流中的數據,並將bodyUsed狀態改成已使用。
Body.blob()
使用一個Blob對象來讀取 Response流中的數據,並將bodyUsed狀態改成已使用。【二進制】
Body.formData()
使用一個 FormData 對象來讀取 Response流中的數據,並將bodyUsed狀態改成已使用【表單數據】。
Body.json()
使用一個 JSON 對象來讀取 Response流中的數據,並將bodyUsed狀態改成已使用【json】。
Body.text()
使用一個USVString (文本)
clone() 方法The clone() method of the Request interface creates a copy of the current Request object.

clone() throws a TypeError if the response Body has already been used. In fact, the main reason clone() exists is to allow multiple uses of Body objects (when they are one-use only.)

對象來讀取 Response流中的數據,並將bodyUsed狀態改成已使用。比起XHR來,這些方法讓非文本化的數據使用起來更加簡單,由於這些方法都被 Request 和Response所實現。

返回 response

若是遇到網絡故障,fetch() promise 將會 reject,帶上一個 TypeError 對象。雖然這個狀況常常是遇到了權限問題或相似問題——好比 404 不是一個網絡故障。想要精確的判斷 fetch() 是否成功,須要包含 promise resolved 的狀況,此時再判斷 Response.ok 是否是爲 true。
response的屬性和方法:

Response.type 只讀
包含Response的類型 (例如, basic, cors).
Response.url 只讀
包含Response的URL.
Response.useFinalURL
包含了一個布爾值來標示這是不是該Response的最終URL.
Response.status 只讀
包含Response的狀態碼 (例如, 200 成功).
Response.ok 只讀
包含了一個布爾值來標示該Response成功(狀態碼200-299) 仍是失敗.
Response.statusText 只讀
包含了與該Response狀態碼一致的狀態信息 (例如, OK對應200).
Response.headers 只讀
包含此Response所關聯的Headers 對象.
Response 實現了 Body, 因此如下屬性一樣可用:

Body.bodyUsed 只讀
 包含了一個布爾值來標示該Response是否讀取過Body.
Response.clone()
建立一個Response對象的克隆
Response.error()
返回一個綁定了網絡錯誤的新的Response對象
Response.redirect()
用另外一個URL建立一個新的 response.
Response 實現了 Body, 因此如下方法一樣可用
相關文章
相關標籤/搜索