W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
Fetch API提供了一個(gè) JavaScript 接口用于訪問(wèn)和操作HTTP管道的零件,如請(qǐng)求和響應(yīng)。它還提供了一種全局fetch()方法,可以提供一種簡(jiǎn)單,合理的方式在網(wǎng)絡(luò)上異步獲取資源。
此類功能以前是使用 XMLHttpRequest 實(shí)現(xiàn)的。Fetch提供了一個(gè)更好的替代方法,可以很容易地被其他技術(shù)使用,如Service Workers。Fetch還提供了一個(gè)單一的邏輯位置來(lái)定義其他HTTP相關(guān)的概念,如CORS和HTTP的擴(kuò)展。
請(qǐng)注意,F(xiàn)etch規(guī)格不同于jQuery.ajax(),主要體現(xiàn)在兩個(gè)方面:
基本的Fetch請(qǐng)求非常容易設(shè)置??纯聪旅娴拇a:
var myImage = document.querySelector('img');
fetch('flowers.jpg').then(function(response) {
return response.blob();
}).then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
});
在這里,我們通過(guò)網(wǎng)絡(luò)獲取圖像并將其插入到一個(gè)<img>元素中。最簡(jiǎn)單的用法是fetch()帶一個(gè)參數(shù) - 要獲取的資源的路徑 - 并返回一個(gè)包含響應(yīng)(Response對(duì)象)的promise。
這當(dāng)然只是一個(gè)HTTP響應(yīng),而不是實(shí)際的圖像。為了從響應(yīng)中提取圖像主體內(nèi)容,我們使用blob()方法(在Body mixin混合中定義,由Request對(duì)象和Response對(duì)象實(shí)現(xiàn))。
注意:Body mixin也有類似的方法來(lái)提取其他類型的Body內(nèi)容;請(qǐng)參閱正文部分了解更多信息。
一個(gè)objectURL接著從所提取的Blob創(chuàng)建,然后將其插入img。
獲取請(qǐng)求由內(nèi)容安全策略connect-src指令控制,而不是由它檢索的資源指令控制。
該fetch()方法可以選擇性地接受第二個(gè)參數(shù),一個(gè) init 對(duì)象,允許你控制許多不同的設(shè)置:
有關(guān)可用選項(xiàng)的詳細(xì)說(shuō)明,請(qǐng)參閱fetch()。
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;
});
要使瀏覽器發(fā)送包含憑據(jù)的請(qǐng)求,即使是跨源調(diào)用,請(qǐng)向傳遞給fetch()方法的init對(duì)象添加credentials: 'include':
fetch('https://example.com', {
credentials: 'include'
})
如果您只想在請(qǐng)求URL與調(diào)用腳本位于相同的源時(shí)發(fā)送憑據(jù),請(qǐng)?zhí)砑?nbsp; credentials: 'same-origin'。
// The calling script is on the origin 'https://example.com'
fetch('https://example.com', {
credentials: 'same-origin'
})
要改為確保瀏覽器不在請(qǐng)求中包含憑據(jù),請(qǐng)使用credentials: 'omit'。
fetch('https://example.com', {
credentials: 'omit'
})
使用fetch()開(kāi)機(jī)自檢JSON編碼的數(shù)據(jù)。
var url = 'https://example.com/profile';
var data = {username: 'example'};
fetch(url, {
method: 'POST', // or 'PUT'
body: JSON.stringify(data),
headers: new Headers({
'Content-Type': 'application/json'
})
}).then(res => res.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
可以使用 HTML <input type="file"/> input 元素、FormData () 和fetch()來(lái)上載文件。
var formData = new FormData();
var fileField = document.querySelector("input[type='file']");
formData.append('username', 'abc123');
formData.append('avatar', fileField.files[0]);
fetch('https://example.com/profile/avatar', {
method: 'PUT',
body: formData
})
.then(response => response.json())
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
當(dāng)遇到網(wǎng)絡(luò)錯(cuò)誤或服務(wù)器端的 CORS 配置不正確時(shí),一個(gè)fetch()承諾將拒絕TypeError,盡管這通常意味著權(quán)限問(wèn)題或類似的情況 - 例如,404不構(gòu)成一個(gè)網(wǎng)絡(luò)錯(cuò)誤。一個(gè)成功的fetch()的準(zhǔn)確檢查將包括檢查承諾解決,然后檢查該Response.ok屬性的值為true。代碼看起來(lái)像這樣:
fetch('flowers.jpg').then(function(response) {
if(response.ok) {
return response.blob();
}
throw new Error('Network response was not ok.');
}).then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ', error.message);
});
您可以使用Request()構(gòu)造函數(shù)創(chuàng)建請(qǐng)求對(duì)象,并將其作為fetch()方法參數(shù)傳入,而不是將要請(qǐng)求的資源的路徑傳遞到 fetch () 調(diào)用中。
var myHeaders = new Headers();
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
var myRequest = new Request('flowers.jpg', myInit);
fetch(myRequest).then(function(response) {
return response.blob();
}).then(function(myBlob) {
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
});
Request()接受與該fetch()方法完全相同的參數(shù)。您甚至可以傳入現(xiàn)有的請(qǐng)求對(duì)象來(lái)創(chuàng)建它的副本:
var anotherRequest = new Request(myRequest, myInit);
這非常有用,因?yàn)檎?qǐng)求和響應(yīng)主體只是一個(gè)用途。制作這樣的副本可以讓您再次使用請(qǐng)求/響應(yīng),同時(shí)根據(jù)需要改變init選項(xiàng)。復(fù)制必須在閱讀正文之前完成,并且閱讀正文中的正文也將其標(biāo)記為原始請(qǐng)求中的正文。
注意:還有一種clone()方法可以創(chuàng)建副本。如果原始請(qǐng)求或響應(yīng)的主體已經(jīng)被讀取,則創(chuàng)建副本的兩種方法都將失敗,但是讀取克隆的響應(yīng)或請(qǐng)求的主體不會(huì)導(dǎo)致它在原始中被標(biāo)記為已讀。
該Headers接口允許您通過(guò)Headers()構(gòu)造函數(shù)創(chuàng)建自己的headers對(duì)象。headers對(duì)象是名稱到值的簡(jiǎn)單多重映射:
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");
同樣可以通過(guò)傳遞一個(gè)數(shù)組或一個(gè)對(duì)象字面值給構(gòu)造函數(shù)來(lái)實(shí)現(xiàn):
myHeaders = new Headers({
"Content-Type": "text/plain",
"Content-Length": content.length.toString(),
"X-Custom-Header": "ProcessThisImmediately",
});
內(nèi)容可以被查詢和檢索:
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.get("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
myHeaders.delete("X-Custom-Header");
console.log(myHeaders.get("X-Custom-Header")); // [ ]
其中的一些操作只是在 ServiceWorkers 中很有用,但是它們提供了一個(gè)更好的API來(lái)處理headers。
如果使用的headers名不是有效的HTTP Header名稱稱,則所有的Headers方法都會(huì)拋出一個(gè)TypeError。如果有一個(gè)不變的guar,變異操作將會(huì)拋出一個(gè)TypeError(見(jiàn)下文)。否則,他們默默地失敗。例如:
var myResponse = Response.error();
try {
myResponse.headers.set("Origin", "http://mybank.com");
} catch(e) {
console.log("Cannot pretend to be a bank!");
}
headers的一個(gè)很好的用例是在進(jìn)一步處理之前檢查內(nèi)容類型是否正確。例如:
fetch(myRequest).then(function(response) {
var contentType = response.headers.get("content-type");
if(contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then(function(json) { /* process your JSON further */ })
.catch(function(error) { console.log(error); });
由于headers可以在請(qǐng)求中發(fā)送,并在響應(yīng)中收到,并且對(duì)于哪些信息可以并且應(yīng)該是可變的有各種限制,headers對(duì)象具有g(shù)uard屬性。這不會(huì)暴露給Web,但會(huì)影響headers對(duì)象上允許使用的變異操作。
可能的guard值是:
注意:您不能追加或設(shè)置request保護(hù)的Headers的 Content-Length headers。同樣,Set-Cookie不允許插入響應(yīng)頭:ServiceWorkers不允許通過(guò)合成響應(yīng)來(lái)設(shè)置cookie。
正如你上面看到的,當(dāng)fetch() promise被解析時(shí),Response實(shí)例被返回。
您將使用的最常見(jiàn)的響應(yīng)屬性是:
它們也可以通過(guò)JavaScript以編程方式創(chuàng)建,但在ServiceWorkers中,當(dāng)您使用respondWith()方法提供對(duì)接收到的請(qǐng)求的自定義響應(yīng)時(shí),這只會(huì)非常有用:
var myBody = new Blob();
addEventListener('fetch', function(event) { // ServiceWorker intercepting a fetch
event.respondWith(
new Response(myBody, {
headers: { "Content-Type" : "text/plain" }
})
);
});
所述Response()構(gòu)造函數(shù)有兩個(gè)可選的參數(shù)- 一個(gè)用于響應(yīng)的主體,和一個(gè)初始化對(duì)象(類似于接受的Request())
注意:靜態(tài)方法error()只是返回錯(cuò)誤響應(yīng)。同樣,redirect()返回一個(gè)響應(yīng)導(dǎo)致重定向到指定的URL。這些也只與Service Workers有關(guān)。
請(qǐng)求和響應(yīng)都可能包含body數(shù)據(jù)。一個(gè)body是以下任何一種類型的實(shí)例:
Body mixin定義了以下方法來(lái)提取體(由得到的Request和Response實(shí)施)。這些都會(huì)返回一個(gè)最終解決實(shí)際內(nèi)容的承諾。
這使得使用非文本數(shù)據(jù)比使用XHR更容易。
請(qǐng)求體可以通過(guò)傳遞身體參數(shù)來(lái)設(shè)置:
var form = new FormData(document.getElementById('login-form'));
fetch("/login", {
method: "POST",
body: form
});
請(qǐng)求和響應(yīng)(以及擴(kuò)展fetch()功能)都將嘗試智能地確定內(nèi)容類型。請(qǐng)求會(huì)自動(dòng)設(shè)置Content-Type header,如果字典中沒(méi)有設(shè)置。
通過(guò)檢查Window或Worker范圍中的Headers,Request,Response或fetch()是否存在,可以檢測(cè)到Fetch API支持。例如:
if (self.fetch) {
// run my fetch request here
} else {
// do something with XMLHttpRequest?
}
要在不受支持的瀏覽器中使用Fetch,可以使用Fetch Polyfill,為不支持的瀏覽器重新創(chuàng)建功能。
規(guī)范 | 狀態(tài) | 評(píng)論 |
---|---|---|
Fetch | Living Standard | Initial definition |
Feature | Chrome | Edge | Firefox(Gecko) | Internet Explorer | Opera | Safari(WebKit) |
---|---|---|---|---|---|---|
基本的支持 | 支持:42 | 支持:14 | 支持: 39(39) 34(34)[1] 52(52)[2] | 不支持 | 支持:29、28 [1] | 支持:10.1 |
Feature | Android Webview | Chrome for Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
基本的支持 | 支持:42 | 支持:42 | 支持 | 不支持 | ? | 支持:10.1 |
對(duì)應(yīng)的角標(biāo)解釋:
[1]這個(gè)API是在首選項(xiàng)后面實(shí)現(xiàn)的。
[2]在Firefox 52之前,get()只返回指定頭文件中的第一個(gè)值,getAll()返回所有的值。從52開(kāi)始,get()現(xiàn)在返回所有值getAll()并被刪除。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: