fetch 方法的参数
fetch(url, optionObj) 的第一个参数是请求的URL,第二个参数是配置对象,用于定制HTTP请求。
HTTP请求的方法、标头、数据体都在配置对象里面进行配置,以下是一些实例:
POST 请求
const response = await fetch(url, {
method: 'POST', // HTTP 请求的方法,默认为GET; POST、DELETE、PUT都在这个属性设置。
headers: { // 一个对象,用来定制 HTTP 请求的标头。
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: 'foo=bar&lorem=ipsum', // POST 请求的数据体。
});
const json = await response.json();
提交 JSON 数据
const user = { name: 'John', surname: 'Smith' };
const response = await fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
提交表单
const form = document.querySelector('form');
const response = await fetch('/users', {
method: 'POST',
body: new FormData(form)
})
文件上传
如果表单里面有文件选择器,可以用前一个例子的写法,上传的文件包含在整个表单里面,一起提交。
另一种方法是用脚本添加文件,构造出一个表单,进行上传,请看下面的例子:
const input = document.querySelector('input[type="file"]');
const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');
fetch('/avatars', {
method: 'POST',
body: data
});
上传二进制文件时,不用修改标头的Content-Type,浏览器会自动设置。
直接上传二进制数据
fetch()也可以直接上传二进制数据,将 Blob 或 arrayBuffer 数据放在body属性里面。
let blob = await new Promise(resolve =>
canvasElem.toBlob(resolve, 'image/png')
);
let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
fetch 方法配置对象的完整API
const response = fetch(url, {
method: "GET",
headers: {
"Content-Type": "text/plain;charset=UTF-8"
},
body: undefined,
referrer: "about:client",
referrerPolicy: "no-referrer-when-downgrade",
mode: "cors",
credentials: "same-origin",
cache: "default",
redirect: "follow",
integrity: "",
keepalive: false,
signal: undefined
});
fetch()请求的底层用的是 Request() 对象的接口,参数完全一样,因此上面的 API 也是Request()的 API。
以下是各个属性的介绍:
- method
HTTP 请求的方法,默认为GET; 可设置为POST、DELETE、PUT - headers
一个对象,用来定制 HTTP 请求的标头 - body
POST 请求的数据体。 - cache
cache 属性指定如何处理缓存,可以取以下的值:
取值 | 含义 |
---|---|
default | 默认值,先在缓存里面寻找匹配的请求。 |
no-store | 直接请求远程服务器,并且不更新缓存。 |
reload | 直接请求远程服务器,并且更新缓存。 |
no-cache | 将服务器资源跟本地缓存进行比较,有新的版本才使用服务器资源,否则使用缓存。 |
force-cache | 缓存优先,只有不存在缓存的情况下,才请求远程服务器。 |
only-if-cached | 只检查缓存,如果缓存里面不存在,将返回504错误。 |
- mode
mode 属性指定请求的模式
取值 | 含义 |
---|---|
cors | 默认值,允许跨域请求。 |
same-origin | 只允许同源请求。 |
no-cors | 请求方法只限于 GET、POST 和 HEAD,并且只能使用有限的几个简单标头,不能添加跨域的复杂标头,相当于提交表单所能发出的请求。 |
- credentials
credentials属性指定是否发送 Cookie
取值 | 含义 |
---|---|
same-origin | 默认值,同源请求时发送 Cookie,跨域请求时不发送。 |
include | 不管同源请求,还是跨域请求,一律发送 Cookie。 |
omit | 一律不发送。 |
- signal
signal属性指定一个 AbortSignal 实例,用于取消fetch()请求 - keepalive
keepalive属性用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据,默认取值为false - redirect
redirect属性指定 HTTP 跳转的处理方法
取值 | 含义 |
---|---|
follow | 默认值,fetch()跟随 HTTP 跳转。 |
error | 如果发生跳转,fetch()就报错。 |
manual | fetch()不跟随 HTTP 跳转,但是response.url属性会指向新的 URL,response.redirected属性会变为true,由开发者自己决定后续如何处理跳转。 |
- integrity
integrity属性指定一个哈希值,用于检查 HTTP 回应传回的数据是否等于这个预先设定的哈希值 - referrer
referrer属性用于设定fetch()请求的referer标头 - referrerPolicy
referrerPolicy属性用于设定Referer标头的规则
取值 | 含义 |
---|---|
no-referrer-when-downgrade | 默认值,总是发送Referer标头,除非从 HTTPS 页面请求 HTTP 资源时不发送。 |
no-referrer | 不发送Referer标头。 |
origin | Referer标头只包含域名,不包含完整的路径。 |
origin-when-cross-origin | 同源请求Referer标头包含完整的路径,跨域请求只包含域名。 |
same-origin | 跨域请求不发送Referer,同源请求发送 |
strict-origin | Referer标头只包含域名,HTTPS 页面请求 HTTP 资源时不发送Referer标头。 |
strict-origin-when-cross-origin | 同源请求时Referer标头包含完整路径,跨域请求时只包含域名,HTTPS 页面请求 HTTP 资源时不发送该标头。 |
unsafe-url | 不管什么情况,总是发送Referer标头。 |
fetch方法的写法
使用Promise
fetch(url, optionObj)
.then(...)
.catch(...)
使用 await
try {
let response = await fetch(url, optionObj);
return await response.json();
} catch (error) {
console.log('Request Failed', error);
}
Response 对象
fetch()请求成功以后,得到的是一个 Response 对象。它对应服务器的 HTTP 回应。
Response 对象的同步属性
- Response.ok
Response.ok属性返回一个布尔值,表示请求是否成功,true对应 HTTP 请求的状态码 200 到 299,false对应其他的状态码。 - Response.status
Response.status属性返回一个数字,表示 HTTP 回应的状态码(例如200,表示成功请求)。 - Response.statusText
Response.statusText属性返回一个字符串,表示 HTTP 回应的状态信息(例如请求成功以后,服务器返回"OK")。 - Response.url
Response.url属性返回请求的 URL。如果 URL 存在跳转,该属性返回的是最终 URL。 - Response.type
Response.type属性返回请求的类型
取值 | 含义 |
---|---|
basic | 普通请求,即同源请求。 |
cors | 跨域请求。 |
error | 网络错误,主要用于 Service Worker。 |
opaque | 如果fetch()请求的type属性设为no-cors,就会返回这个值,详见请求部分。表示发出的是简单的跨域请求,类似 |
opaqueredirect | 如果fetch()请求的redirect属性设为manual,就会返回这个值,详见请求部分。 |
- Response.redirected
Response.redirected属性返回一个布尔值,表示请求是否发生过跳转。
Response.headers
Response 对象还有一个Response.headers属性,指向一个 Headers 对象,对应 HTTP 回应的所有标头。
以下方法是Headers对象提供的,用以操作标头:
方法名 | 作用 |
---|---|
get() | 根据指定的键名,返回键值。 |
has() | 返回一个布尔值,表示是否包含某个标头。 |
set() | 将指定的键名设置为新的键值,如果该键名不存在则会添加。 |
append() | 添加标头。 |
delete() | 删除标头。 |
keys() | 返回一个遍历器,可以依次遍历所有键名。 |
values() | 返回一个遍历器,可以依次遍历所有键值。 |
entries() | 返回一个遍历器,可以依次遍历所有键值对([key, value])。 |
forEach() | 依次遍历标头,每个标头都会执行一次参数函数。 |
Response对象读取内容的方法
Response对象根据服务器返回的不同类型的数据,提供了不同的读取方法:
方法名 | 作用 |
---|---|
text() | 得到文本字符串。 |
json() | 得到 JSON 对象。 |
blob() | 得到二进制 Blob 对象。 |
formData() | 得到 FormData 表单对象。 |
arrayBuffer() | 得到二进制 ArrayBuffer 对象。 |
注意:上面5个读取方法都是异步的,返回的都是 Promise 对象。必须等到异步操作结束,才能得到服务器返回的完整数据。
取消 fetch 请求
fetch()请求发送以后,如果中途想要取消,需要使用AbortController对象:
let controller = new AbortController();
let signal = controller.signal;
fetch(url, {
signal: controller.signal
});
signal.addEventListener('abort',
() => console.log('abort!')
);
controller.abort(); // 取消
console.log(signal.aborted); // true