[1]概述 [2]fetch請求 [3]自定義參數 [4]post [5]json數據 [6]檢測成功 [7]Headers [8]封裝 ...
前面的話
Fetch API 提供了一個 JavaScript介面,用於訪問和操縱HTTP管道的部分,例如請求和響應。它還提供了一個全局 fetch()方法,該方法提供了一種簡單,合乎邏輯的方式來跨網路非同步獲取資源。本文將詳細介紹fetch的相關內容
概述
跨網路非同步獲取資源的功能以前是使用 XMLHttpRequest實現的。Fetch提供了一個更好的替代方法,可以很容易地被其他技術使用,例如 Service Workers。Fetch還提供了單個邏輯位置來定義其他HTTP相關概念,例如 CORS和HTTP的擴展
fetch 規範與 jQuery.ajax() 主要有兩種方式的不同
1、當接收到一個代表錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記為 reject, 即使該 HTTP 響應的狀態碼是 404 或 500。相反,它會將 Promise 狀態標記為 resolve (但是會將 resolve 的返回值的 ok 屬性設置為 false ), 僅當網路故障時或請求被阻止時,才會標記為 reject
2、預設情況下, fetch 不會從服務端發送或接收任何 cookies,如果站點依賴於用戶 session,則會導致未經認證的請求(要發送 cookies,必須設置 credentials 選項)
fetch請求
一個基本的 fetch請求設置起來很簡單。這裡我們通過網路獲取一個圖像並將其插入到一個 <img> 元素中。最簡單的用法是只提供一個參數用來指明想fetch到的資源路徑,然後返回一個包含響應結果的promise(一個 Response 對象)
let myImage = document.querySelector('img'); fetch('flowers.jpg') .then(function(response) { return response.blob(); }) .then(function(myBlob) { let objectURL = URL.createObjectURL(myBlob); myImage.src = objectURL; });
自定義參數
fetch() 接受第二個可選參數,一個可以控制不同配置的 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; });
post
// 通過fetch獲取百度的錯誤提示頁面 fetch('https://www.baidu.com/search/error.html', { method: 'POST', body: JSON.stringify({a:1}), headers: { ...new Headers(headers), 'Content-Type': 'application/json' } }) .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) })
JSON數據
// 通過fetch獲取百度的錯誤提示頁面 fetch('https://www.baidu.com/rec?platform=wise&ms=1&rset=rcmd&word=123&qid=11327900426705455986&rq=123&from=844b&baiduid=A1D0B88941B30028C375C79CE5AC2E5E%3AFG%3D1&tn=&clientWidth=375&t=1506826017369&r=8255', { // 在URL中寫上傳遞的參數 method: 'GET', headers: new Headers({ 'Accept': 'application/json' // 通過頭指定,獲取的數據類型是JSON }) }) .then((res)=>{ return res.json() // 返回一個Promise,可以解析成JSON }) .then((res)=>{ console.log(res) // 獲取JSON數據 })
檢測成功
如果遇到網路故障,fetch() promise 將會 reject,帶上一個 TypeError 對象。雖然這個情況經常是遇到了許可權問題或類似問題——比如 404 不是一個網路故障。想要精確的判斷 fetch() 是否成功,需要包含 promise resolved 的情況,此時再判斷 Response.ok 是不是為 true
fetch('flowers.jpg').then(function(response) { if(response.ok) { response.blob().then(function(myBlob) { var objectURL = URL.createObjectURL(myBlob); myImage.src = objectURL; }); } else { console.log('Network response was not ok.'); } }) .catch(function(error) { console.log('There has been a problem with your fetch operation: ' + error.message); });
Headers
使用 Headers 的介面,可以通過 Headers() 構造函數來創建一個自己的 headers 對象。一個 headers 對象是一個簡單的多名值對:
var content = "Hello World"; var myHeaders = new Headers(); myHeaders.append("Content-Type", "text/plain"); myHeaders.append("Content-Length", content.length.toString()); myHeaders.append("X-Custom-Header", "ProcessThisImmediately");
也可以傳一個多維數組或者對象字面量:
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"); console.log(myHeaders.get("Content-Length")); // 11 console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"] myHeaders.delete("X-Custom-Header"); console.log(myHeaders.getAll("X-Custom-Header")); // [ ]
封裝
下麵是筆者在react中對fetch的精簡版封裝
const fetchModule = ({url, method, data, headers, success, fail}) => { fetch(url, { method: method || 'get', body: JSON.stringify(data), headers: new Headers({...headers, 'Content-Type': 'application/json'}) }) .then(res => { res.json().then(resData => { if (res.ok) { // 成功後的回調函數 success && success(resData.result) } else { // 失敗後的回調函數 fail && fail(resData.err) } }) }) .catch(err => { }) } export default fetchModule