js fetch


Ajax是基於XMLHttpRequest 封裝的網絡請求API. XMLHttpRequest 並不是專為Ajax而設計的. 雖然各種框架對 XHR 的封裝已經足夠好用, 但我們可以做得更好。更好用的API是 fetch 。下面簡單介紹 window.fetch 方法, 在最新版的 Firefox 和 Chrome 中已經提供支持。

XMLHttpRequest

使用XHR的方式大致如下:

// 獲取 XHR 非常混亂!
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
  request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
  try {
    request = new ActiveXObject('Msxml2.XMLHTTP');
  } 
  catch (e) {
    try {
      request = new ActiveXObject('Microsoft.XMLHTTP');
    } 
    catch (e) {}
  }
}

// 打開連接, 發送數據.
request.open('GET', 'https://davidwalsh.name/ajax-endpoint', true);
request.send(null);

我們可以看出, XHR 其實是很雜亂的; 當然, 通過 JavaScript 框架可以很方便地使用XHR。

fetch 的基本使用

// url (必須), options (可選)
fetch('/some/url', {
    method: 'get'
}).then(function(response) {

}).catch(function(err) {
    // 出錯了;等價於 then 的第二個參數,但這樣更好用更直觀 :(
});

 fetch API 也使用了Promise來處理結果/回調

自定義請求頭信息極大地增強了請求的靈活性。我們可以通過 new Headers() 來創建請求頭:

// 創建一個空的 Headers 對象,注意是Headers,不是Header
var headers = new Headers();

// 添加(append)請求頭信息
headers.append('Content-Type', 'text/plain');
headers.append('X-My-Custom-Header', 'CustomValue');

// 判斷(has), 獲取(get), 以及修改(set)請求頭的值
headers.has('Content-Type'); // true
headers.get('Content-Type'); // "text/plain"
headers.set('Content-Type', 'application/json');

// 刪除某條請求頭信息(a header)
headers.delete('X-My-Custom-Header');

// 創建對象時設置初始化信息
var headers = new Headers({
    'Content-Type': 'text/plain',
    'X-My-Custom-Header': 'CustomValue'
});

可以使用的方法包括: append, has, get, set, 以及 delete 。需要創建一個 Request 對象來包裝請求頭:

var request = new Request('/some-url', {
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
});

fetch(request).then(function() { /* handle response */ });

 

Request 簡介

Request 對象表示一次 fetch 調用的請求信息。傳入 Request 參數來調用 fetch, 可以執行很多自定義請求的高級用法:

  • method - 支持 GETPOSTPUTDELETEHEAD
  • url - 請求的 URL
  • headers - 對應的 Headers 對象
  • referrer - 請求的 referrer 信息
  • mode - 可以設置 corsno-corssame-origin
  • credentials - 設置 cookies 是否隨請求一起發送。可以設置: omitsame-origin
  • redirect - followerrormanual
  • integrity - subresource 完整性值(integrity value)
  • cache - 設置 cache 模式 (defaultreloadno-cache)

Request 的示例如下:

var request = new Request('/users.json', {
    method: 'POST', 
    mode: 'cors', 
    redirect: 'follow',
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
});

// 使用!
fetch(request).then(function() { /* handle response */ });

只有第一個參數 URL 是必需的。在 Request 對象創建完成之后, 所有的屬性都變為只讀屬性. 請注意, Request 有一個很重要的 clone 方法, 特別是在 Service Worker API 中使用時 —— 一個 Request 就代表一串流(stream), 如果想要傳遞給另一個 fetch 方法,則需要進行克隆。

fetch 的方法簽名(signature,可理解為配置參數), 和 Request 很像, 示例如下:

fetch('/users.json', {
    method: 'POST', 
    mode: 'cors', 
    redirect: 'follow',
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
}).then(function() { /* handle response */ });

Response 簡介

Response 代表響應, fetch 的 then 方法接收一個 Response 實例, 當然你也可以手動創建 Response 對象 —— 比如在 service workers 中可能會用到. Response 可以配置的參數包括:

  • type - 類型,支持: basiccors
  • url
  • useFinalURL - Boolean 值, 代表 url 是否是最終 URL
  • status - 狀態碼 (例如: 200404, 等等)
  • ok - Boolean值,代表成功響應(status 值在 200-299 之間)
  • statusText - 狀態值(例如: OK)
  • headers - 與響應相關聯的 Headers 對象.
// 在 service worker 測試中手動創建 response
// new Response(BODY, OPTIONS)
var response = new Response('.....', {
    ok: false,
    status: 404,
    url: '/'
});

// fetch 的 `then` 會傳入一個 Response 對象
fetch('/')
    .then(function(responseObj) {
        console.log('status: ', responseObj.status);
    });

Response 提供的方法如下:

  • clone() - 創建一個新的 Response 克隆對象.
  • error() - 返回一個新的,與網絡錯誤相關的 Response 對象.
  • redirect() - 重定向,使用新的 URL 創建新的 response 對象..
  • arrayBuffer() - Returns a promise that resolves with an ArrayBuffer.
  • blob() - 返回一個 promise, resolves 是一個 Blob.
  • formData() - 返回一個 promise, resolves 是一個 FormData 對象.
  • json() - 返回一個 promise, resolves 是一個 JSON 對象.
  • text() - 返回一個 promise, resolves 是一個 USVString (text).

處理 JSON響應

假設需要請求 JSON —— 回調結果對象 response 中有一個json()方法,用來將原始數據轉換成 JavaScript 對象:

fetch('https://davidwalsh.name/demo/arsenal.json').then(function(response) { 
    // 轉換為 JSON
    return response.json();
}).then(function(j) {
    // 現在, `j` 是一個 JavaScript object
    console.log(j); 
});

當然這很簡單 , 只是封裝了 JSON.parse(jsonString) 而已, 但 json 方法還是很方便的。

處理基本的Text / HTML響應

JSON 並不總是理想的請求/響應數據格式, 那么我們看看如何處理 HTML或文本結果:

fetch('/next/page')
.then(function(response) {
    return response.text();
}).then(function(text) { 
    // 
})

處理Blob結果

如果你想通過 fetch 加載圖像或者其他二進制數據, 則會略有不同:

fetch('flowers.jpg')
    .then(function(response) {
      return response.blob();
    })
    .then(function(imageBlob) {
      document.querySelector('img').src = URL.createObjectURL(imageBlob);
    });

fetch 是個很實用的API , 當前還不允許取消請求, 這使得很多程序員暫時不會考慮它。

新的 fetch API 比起 XHR 更簡單也更智能。畢竟,它就是專為AJAX而設計的, 具有后發優勢. 而我已經迫不及待地使用了, 即使現在兼容性還不是那么好!IE並不兼容fetch, 我在項目中也遇到這個問題在引用的fetch的地方引用 isomorphic-fetch 解決。

默認不帶 cookie

原文鏈接:https://juejin.im/entry/574512b7c26a38006c43567c


免責聲明!

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



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