Fetch API
Fetch API
提供了一個 JavaScript 接口,用於訪問和操縱HTTP的請求和響應等。提供了一個全局 fetch()
方法來跨網絡異步獲取資源。
與AJAX的區別
Fetch 規范與 jQuery.ajax() 主要有三種方式的不同:
- 當接收到一個代表錯誤的 HTTP 狀態碼, 即使響應的 HTTP 狀態碼是 404 或 500。從
fetch()
返回的 Promise 不會被標記為 reject,相反,會標記為 resolve (但是會把 resolve 的返回值的ok
屬性設置為 false ),僅當網絡故障時或請求被阻止時,才會標記為 reject。 fetch()
可以接收跨域 cookies;也可以使用fetch()
建立起跨域會話。fetch
不會發送 cookies。除非你使用了credentials 的初始化選項
Fetch()示例
給fetch()
提供一個參數指明資源路徑,會返回一個包含響應結果的promise。當然它只是一個 HTTP 響應,為了獲取JSON的內容,我們需要使用 json()
方法:
默認發送GET請求
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
帶參數的GET請求:
var id=1
fetch(`https://www.easy-mock.com/mock/5f507e38a758c95f67d6eb42/fetch/getmsg?id=${id}`)
.then(response => response.json())
.then(data => console.log(data));
發送POST請求
var data={
id:'1',
}
fetch('https://www.easy-mock.com/mock/5f507e38a758c95f67d6eb42/fetch/postmsg',{
method:'POST',
body:data
})
.then(response => response.json())
.then(data => console.log(data));
Fetch()
用於發起獲取資源的請求。它返回一個 promise,這個 promise 會在請求響應后被 resolve,並傳回 Response 對象。當遇到網絡錯誤時,fetch()
返回的 promise 會被 reject,並傳回 TypeError
。成功的 fetch() 檢查不僅要包括 promise 被 resolve,還要包括 Response.ok
屬性為 true。HTTP 404 狀態並不被認為是網絡錯誤。
語法
fetch(input,{init});
參數
input
——定義要獲取的資源,可以是:
init
—— 可選 | 一個配置項對象,包括所有對請求的設置。可選的參數有:
var myInit={
//請求的 body 信息 //如:Blob、BufferSource、FormData、URLSearchParams 或者 USVString 對象
body: JSON.stringify(data), //這里必須匹配 'Content-Type' //注意 GET 或 HEAD 方法的請求不能包含 body 信息。
//請求的 cache 模式。//如:default, no-cache, reload, force-cache, only-if-cached
cache: 'no-cache',
//請求的 credentials。//包括:omit、same-origin,include
credentials: 'same-origin',
//請求的頭信息
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
//請求使用的方法 //如:GET, POST, PUT, DELETE等
method: 'POST',
//請求的模式 //如 cors、 no-cors 或者 same-origin。
mode: 'cors',
//重定向模式 //如 follow|自動重定向, error|如果產生重定向將自動終止並且拋出一個錯誤, manual|手動處理重定向
redirect: 'follow',
//USVString //如 no-referrer、client或一個 URL。默認是 client
referrer: 'no-referrer',
}
發送帶憑據的請求
//發送包含憑據的請求
fetch('https://example.com', {
credentials: 'include'
})
//如果你只想在請求URL與調用腳本位於同一起源處時發送憑據
fetch('https://example.com', {
credentials: 'same-origin'
})
//確保瀏覽器不在請求中包含憑據
fetch('https://example.com', {
credentials: 'omit'
})
上傳json數據
var data = {username: 'example'};
fetch('https://example.com/profile', {
method: 'POST',
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));
上傳文件
var formData = new FormData();
var fileField = document.querySelector("input[type='file']");// 獲取<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));
上傳多個文件
var formData = new FormData();/
var photos = document.querySelector("input[type='file'][multiple]");
formData.append('title', 'My Vegas Vacation');
// formData 只接受文件、Blob 或字符串,不能直接傳遞數組,所以必須循環嵌入
for (let i = 0; i < photos.files.length; i++) {
formData.append('photo', photos.files[i]);
}
fetch('https://example.com/posts', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
檢測請求是否成功
如果遇到網絡故障,
fetch()
promise 將會 reject,帶上一個TypeError
對象。雖然這個情況經常是遇到了權限問題或類似問題——比如 404 不是一個網絡故障。想要精確的判斷fetch()
是否成功,需要包含 promise resolved 的情況,此時再判斷Response.ok
是不是為 true。類似以下代碼:
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);
});
自定義請求對象
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;
});
與xml的區別
與xml不同的是,Fetch 可以很容易地被其他技術使用,例如
Service Workers
。它還提供了專門的邏輯空間來定義其他與 HTTP 相關的概念,例如 CORS 和 HTTP 的擴展。Fetch 提供了對Request
和Response
(以及其他與網絡請求有關的)對象的通用定義,使之應用於更多場景。
下面是Fetch API的三個接口:Headers、Rquest、Response:
1.Headers
Headers 接口允許您對HTTP請求和響應頭執行各種操作。 包括檢索,設置,添加和刪除。可以通過 Headers()
構造函數來創建一個你自己的 headers 對象
方法
append()
——給現有的header添加一個值, 或者添加一個未存在的header並賦值.delete()
——從Headers對象中刪除指定header.entries()
——以 迭代器 的形式返回Headers對象中所有的鍵值對get()
——以 ByteString 的形式從Headers對象中返回指定header的全部值has()
——以布爾值的形式從Headers對象中返回是否存在指定的header
示例
let myHeaders = new Headers();
myHeaders.append('Content-Type', 'text/xml');
//可以傳一個多維數組或者對象字面量來創建:
myHeaders = new Headers({
"Content-Type": "text/plain",
"X-Custom-Header": "ProcessThisImmediately",
});
//內容可以獲取與修改
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.append("X-Custom-Header", "AnotherValue");
console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
myHeaders.delete("X-Custom-Header");
console.log(myHeaders.getAll("X-Custom-Header")); // [ ]
2.Request
Request接口用來表示資源請求。可以通過 Request()
構造函數來創建一個你自己的 Request對象
屬性
method
——只讀| 包含請求的方法url
——只讀| 包含請求的urlheaders
——只讀| 包含請求相關的Headers對象mode
——只讀| 包含請求模式credentials
——只讀| 包含請求的證書cache
——只讀| 包含請求的緩存模式
示例
//示例1
const myRequest = new Request('http://localhost/flowers.jpg');//創建一個request對象
const myURL = myRequest.url; // http://localhost/flowers.jpg
const myMethod = myRequest.method; // GET
const myCred = myRequest.credentials; // omit
//示例2
const myRequest = new Request('http://localhost/api', {method: 'POST', body: '{"foo":"bar"}'});
const myURL = myRequest.url; // http://localhost/api
const myMethod = myRequest.method; // POST
const myCred = myRequest.credentials; // omit
//可以將Request對象作為參數傳遞給fetch()
fetch(myRequest)
.then(response => response.blob())
.then(blob => {
myImage.src = URL.createObjectURL(blob);
});
3.Response
Response 接口呈現了對一次請求的響應數據。Response實例是在 fetch()
處理完 promise 之后返回的。你也可以通過 Response()
構造函數來創建一個你自己的 Response對象
屬性
headers
——只讀| 包含此 Response 所關聯的 Headers對象ok
——只讀| 包含了一個布爾值,標示該 Response 成功(HTTP 狀態碼的范圍在 200-299)redirected
——只讀| 表示該 Response 是否來自一個重定向,如果是的話,它的 URL 列表將會有多個條目status
——只讀| 包含 Response 的狀態碼 (例如200
表示成功)statusText
——只讀| 包含了與該 Response 狀態碼一致的狀態信息(例如,OK對應200
)type
——只讀| 包含 Response 的類型(例如,basic
、cors
)url
——只讀| 包含 Response 的URL
示例
調用了
fetch()
獲取一張圖片並將其顯示在 HTML 的 IMG 標簽中 ,fetch()
函數返回了一個 Promise,它使用 Response 對象進行解析.。你會注意到,由於我們正在請求一張圖片,我們需要運行blob
為響應提供正確的 MIME 類型
const image = document.querySelector('.my-image');
fetch('flowers.jpg').then(function(response) {
return response.blob();
}).then(function(blob) {
const objectURL = URL.createObjectURL(blob);
image.src = objectURL;
});
Body
Body
mixin 提供了與 response/request 中的 body 有關的方法,可以定義它的內容形式以及處理方式。
Body定義了以下方法(這些方法都被 Request
和Response
所實現)以獲取 body 內容。這些方法都會返回一個被解析后的Promise
對象和數據