使用 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()
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
: 請求使用的方法,如GET、
POST、put/delete/option/...
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 ofno-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 43, fetch() 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}