0. 前言

尽管 Axios官网 对其的介绍非常详细,但是为了方便,还是决定将一些地方以自己便于理解的方式简要记录下来。

PS:一般自己学习Axios直接通过使用CDN引入即可(如果速度较慢可以将 js 文件下载到本地引入),而在项目中才使用npm方式安装。

1. Axios 是什么?

Axios 是一个基于Promise的HTTP客户端,用于浏览器和node.js环境。它是一个开源库,提供了一种简单、优雅的方式来处理HTTP请求。Axios的主要特性包括:

  • 支持浏览器和node.js环境。
  • 支持Promise API。
  • 能够拦截请求和响应。
  • 自动转换JSON数据。
  • 客户端支持保护安全免受XSRF攻击。

Axios的常见用途包括:

  • 发送HTTP请求,如GET、POST、PUT、DELETE等。
  • 处理请求和响应的拦截器。
  • 客户端保护,防止XSRF攻击。
  • 取消请求。
  • 自动转换JSON数据。

2. JSON Server

在前端开发过程中,我们需要实时与后端进行数据交互。然而大多数时候,前端开发都是在没有后端数据提供的情况下进行的,这时我们就需要用到假 API 模拟。而 JSON Server 就可以为我们提供假 API。

2.1 JSON Server是什么?

JSON Server 官方介绍:

Get a full fake REST API with zero coding in less than 30 seconds (seriously)

Created with <3 for front-end developers who need a quick back-end for prototyping and mocking.

翻译过来的大致意思就是:

不到 30 秒的时间内获得一个完整的假 REST API,零编码(认真的)

使用 <3 创建,适用于需要快速后端进行原型设计和模拟的前端开发人员。

2.2 JSON Server使用

仅需简单的三步:

1、安装

1
npm install json-server

2、创建一个 db.json 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"posts": [
{ "id": "1", "title": "a title", "views": 100 },
{ "id": "2", "title": "another title", "views": 200 }
],
"comments": [
{ "id": "1", "text": "a comment about post 1", "postId": "1" },
{ "id": "2", "text": "another comment about post 1", "postId": "1" }
],
"profile": {
"name": "typicode"
}
}

3、启动服务,将其传递给 JSON 服务器 CLI

PS:服务启动时一定要确保当前工作目录定位在 db.json 所在文件夹下

1
npx json-server db.json

启动服务后就可以通过REST API风格访问 http://localhost:3000/ 拿到对应数据了。

PS:不知道 REST API 风格的小伙伴可以参考这篇文章的 RESTFul 编程风格 介绍部分:【第6章】 RESTFul编程风格

3. Axios 的使用

1、安装

1
npm install axios

2、在需要使用的组件引入

1
import axios from 'axios';

3.1 Axios API

格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
axios({
//请求方法,GET/POST/...
method: 'post',
//请求路径
url: 'http://localhost:3000/posts',
//请求数据
data: {
"id": 3,
"title": "今天天气不错",
"views": 300
}
}).then(response => {
//成功的回调
//response代表服务器响应的所有的数据,包含了响应头,响应体. response.data 代表的是接口响应的核心数据
console.log(response.data);
}).catch(err => {
//失败的回调
console.log(err);
});

示例:

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
// 发起一个get请求
axios({
method: 'get',
url: 'http://localhost:3000/posts/1'
}).then(response => {
console.log(response.data);
}).catch(err => {
console.log(err);
});


// 发起一个post请求
axios({
method: 'post',
url: 'http://localhost:3000/posts',
//设置请求体
data: {
"id": 3,
"title": "今天天气不错",
"views": 300
}
})
.then(response => {
console.log(response.data);
}).catch(err => {
console.log(err);
});

3.2 请求式别名

为了方便起见,Axios 已经为所有支持的请求方法提供了别名。

格式:axios.请求方式(url[, data[, config]])

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 发起一个get请求
axios.get('http://localhost:3000/posts/1')
.then(response => {
console.log(response.data);
}).catch(err => {
console.log(err);
});


// 发起一个post请求
let post = {
"id": 4,
"title": "今天心情不错",
"views": 400
}

axios.post('http://localhost:3000/posts', post)
.then(response => {
console.log(response.data);
}).catch(err => {
console.log(err);
});

4. 默认配置

请求配置 里的配置选项都是可以设置默认配置的。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//设置默认的请求类型为 POST
axios.defaults.method = 'post';
//设置默认基础 URL
axios.defaults.baseURL = 'http://localhost:3000';

// 发起一个post请求
axios({
url: '/posts',
data: {
"id": 5,
"title": "今天心情一般般",
"views": 500
}
}
).then(response => {
console.log(response.data);
});

由于上方设置了默认的请求类型为 POST 和基础 URL,在下面发起请求时没有显式指定请求方法,Axios 将默认使用 POST 方法。url: '/posts', 这里的 url 字段指定了请求的路径。但是没有提供完整 URL,Axios 会将这个基础 URL 添加到请求的路径前面。所以实际请求的 URL 将是 http://localhost:3000/posts

5. 拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 添加请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求之前做些什么
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);

// 添加响应拦截器
axios.interceptors.response.use(
response => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
},
error => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});

可以给自定义的 axios 实例添加拦截器:

1
2
3
4
5
6
7
8
9
// Axios实例(下面会进行介绍)
const instance = axios.create({
/*...*/
});

// 添加请求拦截器
instance.interceptors.request.use(/*...*/);
// 添加响应拦截器
instance.interceptors.response.use(/*...*/);

6. Axios 实例

Axios 实例是使用 Axios 库创建的一个定制化的 HTTP 客户端对象。这个实例是基于 Axios 的核心功能,但是可以拥有自己的配置,比如基础 URL、默认的请求头、超时时间等。通过创建 Axios 实例,你可以为不同的 API 或服务配置不同的设置,而不必每次发送请求时都重复设置这些参数。

格式:axios.create([config])

使用示例

创建实例

1
2
3
4
5
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});

这里,axios.create() 方法接受一个配置对象,用于创建一个新的 Axios 实例。这个实例会继承 Axios 的所有方法和属性,但是会使用你提供的配置作为默认值。

使用实例发送请求

1
2
3
4
5
6
7
instance.get('/user')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});

使用创建的 Axios 实例发送请求时,它会使用你在创建实例时提供的配置。在这个例子中,instance 会使用https://api.example.com/user 作为请求的 URL。

默认配置

创建 Axios 实例时设置的配置会成为该实例的默认配置。这意味着如果你在发送请求时没有提供特定的配置,Axios 实例会使用默认配置。

拦截器

Axios 实例允许你添加请求和响应拦截器,这些拦截器可以在请求发送之前或响应到达之前进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
instance.interceptors.request.use(config => {
// 在发送请求之前做些什么
return config;
}, error => {
// 对请求错误做些什么
return Promise.reject(error);
});
instance.interceptors.response.use(response => {
// 对响应数据做点什么
return response;
}, error => {
// 对响应错误做点什么
return Promise.reject(error);
});

拦截器可以用来修改请求配置、处理错误、添加日志、显示加载指示器等。

总结

通过创建 Axios 实例,你可以为不同的 API 请求创建不同的配置,这样可以提高代码的可维护性和可复用性。例如,如果你正在开发一个前端应用,并且需要与多个后端服务进行通信,为每个服务创建一个 Axios 实例并配置好相应的默认参数,可以让你的代码更加清晰和模块化。

7. 网络请求跨域解决方案

网络请求跨域,通常指的是当一个网页或脚本尝试访问或请求另一个不同源(不同协议、不同域名、不同端口)的网页或资源时,由于浏览器的同源策略(Same-Origin Policy)限制,这种请求会被阻止。

跨域错误提示信息

跨域错误提示信息

解决方案

非常简单,直接在 vite.config.ts 中配置即可:

1
2
3
4
5
6
7
8
9
server: {
proxy: {
'/api': {
target: '<url>',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}

配置详解:

  • server:开发服务器的配置对象。
  • proxy:在这个对象中,您可以定义代理规则,告诉开发服务器如何处理特定的API请求。
  • '/api':这是一个匹配请求路径的正则表达式。当请求的路径以 /api 开头时,这个代理规则会被应用。
  • target:这是目标服务器的URL,您的API请求将会被代理到这个地址。
  • changeOrigin:设置为 true 时,代理服务器会修改请求头中的 Origin 字段,使得请求看起来像是来自于目标服务器,从而绕过某些基于Origin的跨域限制。
  • rewrite:重写请求路径函数。在这个例子中,rewrite函数会去除请求路径中的/api前缀。例如,如果请求/api/userinfo,代理服务器会将请求转发到 http://localhost:8080/userinfo

解决完跨域配置后,记得要重启服务器才行哦!

其他

requrst.js

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
63
//定制请求的实例

//导入axios npm install axios
import axios from 'axios';

import { ElMessage } from 'element-plus'
//定义一个变量,记录公共的前缀 , baseURL
//const baseURL = 'http://localhost:8080';
const baseURL = '/api';
const instance = axios.create({ baseURL })

import {useTokenStore} from '@/stores/token.js'
//添加请求拦截器
instance.interceptors.request.use(
(config)=>{
//请求前的回调
//添加token
const tokenStore = useTokenStore();
//判断有没有token
if(tokenStore.token){
config.headers.Authorization = tokenStore.token
}
return config;
},
(err)=>{
//请求错误的回调
Promise.reject(err)
}
)

/* import {useRouter} from 'vue-router'
const router = useRouter(); */

import router from '@/router'
//添加响应拦截器
instance.interceptors.response.use(
result => {
//判断业务状态码
if(result.data.code===0){
return result.data;
}

//操作失败
//alert(result.data.msg?result.data.msg:'服务异常')
ElMessage.error(result.data.msg?result.data.msg:'服务异常')
//异步操作的状态转换为失败
return Promise.reject(result.data)

},
err => {
//判断响应状态码,如果为401,则证明未登录,提示请登录,并跳转到登录页面
if(err.response.status===401){
ElMessage.error('请先登录')
router.push('/login')
}else{
ElMessage.error('服务异常')
}

return Promise.reject(err);//异步的状态转化成失败的状态
}
)

export default instance;