网络请求 | Fetch_API 基本用法

Fetch API 是基于Promise的

特点

  • 使用Promise,不使用回调函数
  • 采用模块化设计
  • 通过数据流对象处理数据,可以提高网站性能

fetch()方法是暴露在全局作用域中的,包括主页面执行线程、模块和工作线程。调用这个方法,浏览器就会向给定的URL发送请求

1. 分派请求

fetch()只有一个必需的参数,多数情况下,这个参数是要获取资源的URL,并且返回一个Promise

1
2
let r = fetch('/bar');
console.log(r); // Promise <pending>

请求完成、资源可用时,Promise会解决为一个Response对象,这个对象是API封装的,可以通过它获取相应的资源

1
2
3
4
5
6
7
8
9
const hotSongsRequest = (id) => {
const url = BASE_URL + '/artist/top/song?id=' + id;
fetch(url).then(response => {
console.log(response) // 关注Response的打印结果
})
};

const BASE_URL = 'http://localhost:3000';
hotSongsRequest(6452);

打印结果:

2. 读取响应

通过text()方法获取结果内容,这个方法返回一个Promise

1
2
3
4
5
6
7
8
9
10
const hotSongsRequest = (id) => {
const url = BASE_URL + '/artist/top/song?id=' + id;
fetch(url).then(response => response.text().then(value => {
let data = JSON.parse(value).songs;
console.log(data);
}))
};

const BASE_URL = 'http://localhost:3000';
hotSongsRequest(6452);

打印结果:

内容的结构通常是打平的

1
2
3
4
5
6
7
8
const hotSongsRequest = (id) => {
const url = BASE_URL + '/artist/top/song?id=' + id;
fetch(url).then(response => response.text())
.then(value => console.log(JSON.parse(value).songs))
};

const BASE_URL = 'http://localhost:3000';
hotSongsRequest(6452);

3. 处理状态码和请求失败

从下图看,Response对象中含有status和statusText属性检查响应状态

补课:HTTP状态码

注意:

  • 可以显式地设置fetch()在遇到重定向时的行为,不过默认行为是跟随重定向并返回状态码不是300-399的响应,跟随重定向时,响应对象的redirected属性,会被设置为true,而状态码仍然是200
1
2
3
4
5
6
7
8
9
fetch('/permanent-redirect')
.then((response) => {
// 默认行为是跟随重定向直到最终URL
// 这个例子会出现至少两轮网络请求
// <origin url>/permanent-redirect -> <redirect url>
console.log(response.status); // 200
console.log(response.statusText); // OK
console.log(response.redirected); // true
});
  • 只要服务器返回了响应,fetch()的Promise都会解决

下面代码我故意写错端口号:

1
2
3
4
5
6
7
8
const hotSongsRequest = (id) => {
const url = BASE_URL + '/artist/top/song?id=' + id;
let r = fetch(url);
console.log(r);
};

const BASE_URL = 'http://localhost:4000';
hotSongsRequest(6452);

由图可知,Promise的状态为fulfilled

这个行为是合理的,系统级网络协议已经成功完成消息的一次往返传输。至于真正的“成功”请求,则需要在处理响应时再定义。

通常状态码为200 时就会被认为成功了,其他情况可以被认为未成功

为区分这两种情况,可以在状态码非200~299 时检查Response 对象的ok 属性

  • 以下情况会引起fetch()失败而导致Promise被拒绝
    • 服务器没有响应而导致浏览器超时
    • 违反CORS、无网络连接、HTTPS 错配及其他浏览器/网络策略问题都会导致期约被拒绝

4. 自定义选项

只使用URL 时,fetch()会发送GET 请求,只包含最低限度的请求头

要进一步配置如何发送请求,需要传入可选的第二个参数init 对象

init对象可以按照键值对进行填充

1
fetch(url, init)

init配置请看链接:[fetch API](https://developer.mozilla.org/zh-CN/docs/Web/API/fetch

比如我们要发送POST请求,就可以做如下配置:

1
2
3
fetch(url, {
method: 'POST',
})