Fetch API
Fetch
提供了获取资源的接口,可以用于跨域请求,可以看做是 XHR 的替代;实际上手用了一段时间之后呢,感觉和 XHR 差异不是很大,因为前端在 XHR 这块也封装了许多插件,像 axios 这些,都可以实现异步promise
返回了,如果考虑兼容性肯定还是 XHR 更好一些,但是毕竟 fetch 不需要引入其他的包,更方便快捷,易用性也很强。
核心概念
fetch
及其衍生的 API,提供了对请求以及相应的通用定义;还为 CORS / HTTP 原生头信息提供了新的定义;并且fetch
方法不止在window
对象上,在workerGlobalScope
上也有,所以在 nodejs 环境下也可以用这个方法;fetch
方法必须参数为资源路径,返回promise
,相对于原生的 XHR 更方便了。
目前除了 IE 全面不兼容fetch API
以外,其他主流浏览器兼容性较好,但是实验性的一些方法除外。
request | response
request
构造函数:new Request(input[, init])
input
:定义需要fetch
的资源,可以是URL
,也可以是另一个request
对象;init
:可选参数,包括一系列自定义选项:method
:请求方法,大写字符串GET | POST ...
headers
:请求头,一个作为请求头的Headers
对象,或者其内部值为ByteString
的对象字面量;body
:任何需要加入到请求中的 body,blob | formdata | URLSearchParams | USVString
对象,注意GET | HEAD
方法没有 body;mode
:请求模式(是否跨域),可选项cors | no-cors | same-origin | navigate
,默认使用 cors;credentials
:和 XHR 的withCredentials
类似,标记了cookie
如何发送,omit | same-origin | include
,分别表示不发送 cookie,仅发送同源 cookie,发送所有 cookiecache
:请求的缓存模式,可选项default | no-store | reload | no-cache | force-cache | only-if-cached
;redirect
:重定向模式,当服务器返回 300+时该请求的后续动作,可选项:follow
自动重定向,error
重定向自动终止并抛出错误,manual
手动处理重定向;referrer
:http
请求中referrer
指定了跳转到新链接时,头部referrer
携带的信息,可选项no-referrer | client | 指定的 URL
;referrerPolicy
:指定http
头部referrer
字段的值,可选项:no-referrer | no-referrer-when-downgrade | origin | origin-when-cross-origin | unsafe-url
;integrity
:包括请求的subresource integrity
值;
response
可以用构造函数来创建一个response
对象,但更多的情况是从其他 API 返回了一个response
对象;这里主要就介绍下调用fetch
之后返回的 response 对象;
实例对象包含的属性有:
headers
:响应头;ok
:响应状态,布尔值,为true
时http
状态码在 200-299 之间;redirected
:是否来自重定向的响应,如果是,响应的 URL 列表会有多个条目;status
:响应状态码;statusText
:与状态码一致的状态信息;type
:响应的类型,如basic | cors
;url
:响应的 url;useFinalURL
:表示响应是否是最终的 url;body
:响应体,后面会单独介绍;bodyUsed
:布尔值,标记 body 是否被读取过;
实例方法:
clone
:创建实例对象的克隆;error
:该方法返回一个绑定了网络错误的新的相应对象;redirect
:用另一个 URL 创建新的response
对象;body
的所有方法,由于 response 实现了 body 接口,所以也实现了所有方法;
body
body
在fetch API
中代表了请求/响应的正文部分,允许手动声明请求或响应的内容类型以及如何处理;body
提供了一个相关联的主体(字节流),已使用的标志位,MIME 类型;
属性:
body
:主体内容,只读属性,一个readableStream
类型;bodyUsed
:布尔值,只读属性,是否已被读取;
方法,以下的读取方法都返回一个promise
对象,其resolve
的参数类型都是方法对应的读取类型:
arrayBuffer
blob
formData
json
text
实例
由于在request | response
都实现了这些方法和属性,所以可以来看个实例了;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 服务端 nodejs,express
// post method
router.post('/', (req, res, next) => {
// inspect(req);
console.warn(req);
try {
readFile('./test/img/img01.png', (err, data) => {
console.log(data);
if (err) {
throw new Error(err);
}
res.set('Content-Type', 'application/json');
let formdata = {
para1: req.body,
img: data
};
res.send(formdata);
});
} catch (err) {
console.error(err);
}
});
// 客户端
function getUser(params) {
let url = '/user';
let param = {
usercode: '123456',
password: '123456'
};
let p = fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(param)
});
p.then(res => {
console.warn(res);
if (!res.ok) {
throw new Error('net work error');
}
return res.json();
})
.then(res => {
console.warn(res.para1, res.img);
// let fr = new FileReader();
let i8 = new Uint8Array(res.img.data);
let blob = new Blob([i8], {
type: 'image/png'
});
console.warn(blob);
let img = document.querySelector('#img');
img.src = URL.createObjectURL(blob);
img.onload = function (e) {
URL.revokeObjectURL(this.src);
};
})
.catch(err => {
console.error(err);
});
}