window 自带了
window.fetch
方法, 在最新版的 Firefox 和 Chrome 中已经提供支持,其他浏览器还有兼容性问题,要做兼容性处理。
为了解决 fetch 的兼容性,我们使用 Fetch Polyfill 的版本 whatwg-fetch。
npm install --save whatwg-fetch
import 'whatwg-fetch'
也可以用另一个 fetch 版本 isomorphic-fetch
npm install --save isomorphic-fetch
import fetch from "isomorphic-fetch";
二、fetch
的基本使用// url (必须), init对象 (可选)
fetch(url, init).then(function(res) {
// fetch第一次拿到的是整个Response对象,要调用json()方法转成含有json数据的Promise
return res.json();
}).catch(function(err) {
// 中途任何地方出错...在此处理
});
fetch('http://localhost:8082/data/users.json?id=99')
.then(function(res) {
return res.json();
})
.then(function(myJson) {
console.log(myJson);
});
请求参数以json形式传给后端
fetch('/api/getItems', {
body: JSON.stringify(params), //json字符串和对象都可以,推荐使用json字符串,这样可以在控制台network里看到请求参数
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, same-origin, *omit
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
}).then(response => response.json()).then(res => {
console.log(res)
})
请求参数以formData形式传给后端
import qs from 'query-string';
fetch('/api/getItems', {
body: qs.stringify(params), //使用query-string把参数转换成'name=jim&age=22'形式,也可以直接用formData格式作为参数
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, same-origin, *omit
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
method: 'POST'
}).then(response => response.json()).then(res => {
console.log(res)
})
可以通过HTML元素,
FormData()
和fetch()
上传文件。
var formData = new FormData();
var fileField = document.querySelector("input[type='file']");
formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);
fetch("/api/uploadFile", {
method: "PUT",
body: formData
})
.then(response => response.json())
.catch(error => console.error("Error:", error))
.then(response => console.log("Success:", response));
new FormData() 可以直接传一个 form 元素作为参数。
{
body: new FormData(document.getElementById('myForm'))
}
var formData = new FormData();
var photos = document.querySelector("input[type='file'][multiple]");
formData.append('title', 'My Vegas Vacation');
formData.append('photos', photos.files);
fetch('https://example.com/posts', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));
除了传给 fetch()
一个url,你还可以通过使用 Request()
构造函数来创建一个 request 对象,然后再作为参数传给 fetch()
:
var myHeaders = new Headers();
var myInit = {
method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default'
};
var myRequest = new Request('/api/getItems', myInit);
fetch(myRequest).then(function(response) {
return response.json();
}).then(function(res) {
console.log(res)
});
Request()
和 fetch()
接受同样的参数。你甚至可以传入一个已存在的 request 对象来创造一个拷贝:
var anotherRequest = new Request(myRequest,myInit);
这个很有用,因为 request 和 response bodies 只能被使用一次(译者注:这里的意思是因为设计成了 stream 的方式,所以它们只能被读取一次)。创建一个拷贝就可以再次使用 request/response 了,当然也可以使用不同的 init
参数。
注意:
clone()
方法也可以用于创建一个拷贝。它在语义上有一点不同于其他拷贝的方法。其他方法(比如拷贝一个 response)中,如果 request 的 body 已经被读取过,那么将执行失败,然而clone()
则不会失败。
当接收到一个代表错误的 HTTP 状态码时,从 fetch()
返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok
属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。当状态码在200-299之间时,ok
属性才会返回 true。
默认情况下,fetch
不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项为 include)。自从2017年8月25日后,默认的credentials政策变更为same-origin
Firefox也在61.0b13中改变默认值
一个配置项对象,包括所有对请求的设置。可选的参数有:
1. method -
支持 GET
, POST
, PUT
, DELETE
, HEAD
2. headers
- 对应的 Headers
对象
3. body - 请求参数
4. credentials
- 设置 cookies 是否随请求一起发送。
可选值: omit: (默认, 不发送 Cookie)
same-origin:同域下自动发送 Cookie
include:始终发送 Cookie,即使是跨域。
5. mode
- 是否允许跨域请求,以及哪些响应的属性是可读的。
可选值:cors
:(默认, 允许跨域请求,将遵守 CORS 协议)
no-cors:该模式允许来自 CDN 的脚本、其他域的图片和其他一些跨域资源。前提条件是请求的 method 只能是 HEAD、GET 或 POST。而且 js 不能访问 Response 对象中的任何属性
same-origin:要同源,不允许跨域。
navigate:支持导航的模式,仅用于 HTML 导航。
6. cache
- 设置缓存模式。
可选值: default:浏览器在其 HTTP 缓存中查找匹配的请求。
a. 如果匹配并且是新鲜的,它将从缓存中返回。
b. 如果存在匹配但已失效,则浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新。
c. 如果没有匹配,浏览器将发出正常的请求,并且下载的资源更新缓存。
no-store:浏览器从远程服务器获取资源,而不先查看缓存,并且不会使用下载的资源更新缓存。
reload:浏览器从远程服务器获取资源,而不先查看缓存,但随后将使用下载的资源更新缓存。
no-cache:浏览器在其 HTTP 缓存中查找匹配的请求。
a. 如果匹配,新鲜或陈旧,浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新。
b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。
force-cache:浏览器在其 HTTP 缓存中查找匹配的请求。
a. 如果有匹配,新鲜或陈旧,它将从缓存中返回。
b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。
only-if-cached:浏览器在其 HTTP 缓存中查找匹配的请求。只能用在 mode 为 same-origin 的情况下
a. 如果匹配,新鲜或陈旧,将从缓存中返回。
b. 如果没有匹配,浏览器将返回一个错误。
7. referrer
- 请求的引用者(例如:client)
8. redirect
- 定义重定向处理方式。
可选值:follow(默认), error, manual。
9. integrity
- 子资源完整性值。
不管是请求还是响应都能够包含body对象. body也可以是以下任意类型的实例
ArrayBuffer
ArrayBufferView
(Uint8Array等)Blob
/FileURLSearchParams
FormData
Body
类定义了以下方法 (这些方法都被 Request
和Response
所实现)以获取body内容. 这些方法都会返回一个被解析后的Promise
对象和数据.
arrayBuffer()
blob()
json()
text()
formData()
fetch("/api/getItems").then(res => {
return res.json();
});
参考文献:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch