fetch()
可讓您發出類似 XMLHttpRequest (XHR) 的網路要求。
主要差異在於 Fetch API 使用 Promise
更簡便的 API,避免發生要求中的複雜回呼
XMLHttpRequest API。
如果您沒用過 Promise 請先參閱 JavaScript Promise 簡介。
基本擷取要求
以下示範如何透過 XMLHttpRequest
實作
然後使用 fetch
。我們想要求存取網址、取得回應以及剖析
匯出為 JSON
XMLHttpRequest
XMLHttpRequest
需要兩個事件監聽器來處理成功
以及呼叫 open()
和 send()
的情況。
MDN 文件範例。
function reqListener() {
var data = JSON.parse(this.responseText);
console.log(data);
}
function reqError(err) {
console.log('Fetch Error :-S', err);
}
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
擷取
我們的擷取要求如下所示:
fetch('./api/some.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
fetch()
要求只需要一個呼叫就能執行與 XHR 相同的工作
範例。為處理回應,我們會先檢查回應狀態
200,則將回應剖析為 JSON。fetch()
要求的回應是
Stream 物件,也就是說,
我們呼叫了 json()
方法,會傳回 Promise。
串流以非同步方式進行。
回應中繼資料
上例顯示了 Response 物件,以及如何 將回應剖析為 JSON。如何處理您可能會想要的其他中繼資料 可存取的標頭,例如標頭:
fetch('users.json').then(function(response) {
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('Date'));
console.log(response.status);
console.log(response.statusText);
console.log(response.type);
console.log(response.url);
});
回應類型
當我們提出擷取要求時,回應會獲得 response.type
「basic
」,
「cors
」或
「opaque
」。
這些types
會顯示資源的來源,您可以使用這些資源
判斷如何處理回應物件
如果瀏覽器要求相同來源的資源,回應會包含
basic
類型,限制您可以在回應中查看的內容。
如果對另一個來源的資源發出要求,且該來源會傳回
COR 標頭,則類型為 cors
。cors
回應類似於 basic
回應,但會限制
可查看「Cache-Control
」、「Content-Language
」、「Content-Type
」、「Expires
」和
Last-Modified
和Pragma
。
opaque
回應來自未傳回 CORS 的不同來源
標題。如果得到不透明回應,
讀取傳回的資料或查看要求狀態,也就是說
以及要求是否成功
您可以為擷取要求定義模式,藉此只讓某些要求類型 解析。您可以設定的模式如下:
same-origin
只會成功針對相同來源的資產發出要求,且 也會拒絕所有其他要求。cors
允許要求相同來源及其他來源的資產 會傳回適當的 COR 標頭。cors-with-forced-preflight
會執行預檢 查看 再提出要求no-cors
的用途是向其他沒有 CORS 的來源發出要求 標頭並產生opaque
回應,但如 所述,這並非 都可以使用這項工具
如要定義模式,請將選項物件新增為
fetch
要求,然後定義該物件中的模式:
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log('Request successful', text);
})
.catch(function(error) {
log('Request failed', error)
});
Promise 鏈結
實現承諾的一大特色是能夠鏈結在一起。適用對象
fetch()
,可讓您跨擷取要求共用邏輯。
如果您使用的是 JSON API,必須檢查狀態並剖析 每個回應的 JSON。若要簡化程式碼,可以定義狀態和 JSON 會在傳回承諾的單獨函式中剖析,並使用擷取作業 要求僅處理最終資料和錯誤情況。
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}
fetch('users.json')
.then(status)
.then(json)
.then(function(data) {
console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
console.log('Request failed', error);
});
這個範例會定義 status
函式,以便檢查 response.status
和
會傳回已解析的 Promise
Promise.resolve()
、
或已遭拒的承諾使用名稱
Promise.reject()
。
這是 fetch()
鏈結中呼叫的第一個方法。
如果 Promise 已解析,指令碼會呼叫 json()
方法,
從 response.json()
呼叫傳回第二個 Promise,並
物件,當中含有剖析 JSON 檔案。如果剖析失敗,Promise 就會是
且 include 陳述式會執行
這個結構可讓您在所有擷取要求中共用邏輯, 維護、讀取及測試程式碼變得更簡單
POST 要求
有時候,網頁應用程式需要使用 POST 方法呼叫 API,並加入一些
參數中。方法是設定 method
和 body
fetch()
選項中的參數:
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(function (data) {
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
console.log('Request failed', error);
});
透過擷取要求傳送憑證
如要透過 Cookie 等憑證提出擷取要求,請設定要求的
將 credentials
的值設為 "include"
:
fetch(url, {
credentials: 'include'
})