一、什么是Fetch ?
Fetch本質上是一種標準,該標準定義了請求、響應和綁定的流程。
Fetch標準還定義了Fetch () JavaScript API
,它在相當低的抽象級別上公開了大部分網絡功能,我們今天將的主要是Fetch API
。Fetch API
提供了一個獲取資源的接口(包括跨域)。它類似于 XMLHttpRequest
,但新的API提供了更強大和靈活的功能集。
Fetch 的核心在于對 HTTP 接口的抽象,包括 Request
,Response
,Headers,Body,以及用于初始化異步請求的global fetch
二、如何使用Fetch
fetch() 方法的使用
Fetch API 提供了一種全局fetch()方法,該方法位于 WorkerOrGlobalScope 這一個 mixin 中 方法用于發起獲取資源的請求。它返回一個 promise,這個 promise 會在請求響應后被 resolve,并傳回 Response 對象
fetch(input?: Request | string, init?: RequestInit): Promise<Response>
fetch(url, options).then(function(response) {
// 處理 HTTP 響應
}, function(error) {
// 處理網絡錯誤
})
fetch() 參數
fetch方法可以接收兩個參數input
和options
。
input 參數可以是字符串,包含要獲取資源的 URL。也可以是一個 Request 對象。
options 是一個可選參數。一個配置項對象,包括所有對請求的設置。可選的參數有:
method: 請求使用的方法,如 GET、POST。
headers: 請求的頭信息,包含與請求關聯的Headers對象。
body: 請求的 body 信息。注意 GET 或 HEAD 方法的請求不能包含 body 信息
mode: 請求的模式,如 cors、 no-cors 或者 same-origin。
credentials: 請求的 credentials,如 omit、same-origin 或者 include。為了在當前域名內自動發送 cookie , 必須提供這個選項。
常用的fetch請求
HTML
fetch('/index/fetchHtml')
.then((res) => {
return res.text()
}).then((result) => {
document.body.innerHTML += result
})
.catch((err) => {
})
JSON
fetch('/api/user/CaiCai')
.then((res) => {
return res.json()
})
.then((json) => {
console.log(json)
})
.catch((err => {
}))
POST Form
function postForm() {
const form = document.querySelector('form')
const name = encodeURI(document.getElementsByName('name')[0].value)
fetch(`/api/user/${name}`, {
method: 'POST',
body: new FormData(form)
})
}
POST JSON
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'CaiCai',
age: '26',
})
})
fetch注意事項
1. 錯誤處理
fetch只有在網絡錯誤的情況,返回的promise會被reject。成功的 fetch() 檢查不僅要包括 promise 被 resolve,還要包括 Response.ok 屬性為 true。HTTP 404 狀態并不被認為是網絡錯誤,所以Promise的狀態為resolve。
2. credentials 設置
fetch可以通過credentials自己控制發送請求時是否帶上cookie。credentials可設置為include、same-origin、omit。include為了讓瀏覽器發送包含憑據的請求(即使是跨域源)。如果你只想在請求URL與調用腳本位于同一起源處時發送憑據,請添加credentials: 'same-origin'。要改為確保瀏覽器不在請求中包含憑據,請使用credentials: 'omit'。
credentials 默認是“same-origin”,但是以下版本的瀏覽器實現了一個更老版本的fetch規范,其中默認是“忽略”:
Firefox 39-60
Chrome 42 - 67
Safari 10.1 11.1.2
如果您的目標是這些瀏覽器,建議始終對所有fetch請求顯式指定憑據:'同源',而不是依賴于默認
3. 中止
fetch 自身并沒有提供 中止請求的方法。但是部分瀏覽器有實現AbortController,可以通過AbortController中止fetch請求
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 5000);
fetch('/api/user/CaiCai', {
signal, // 在option中加入signal
method: 'POST',
// credentials:'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'CaiCai',
age: '26',
})
}).then((res) => {
return res.json()
}).then((result) => {
console.log(result)
}).catch((err) => {
console.log(err)
})
三、為什么要用Fetch、而不用XHR
1、fetch返回的是promise對象,比XMLHttpRequest的實現更簡潔,fetch 使用起來更簡潔 ,完成工作所需的實際代碼量也更少
2、fetch 可自定義是否攜帶Cookie
3、fetch在ServiceWorker中使用,至于ServiceWorker能有什么優勢,會在未來寫ServiceWorker的時候回寫到