1. What is axios
axios
is a lightweight HTTP
client
Execute requests based on XMLHttpRequest
services HTTP
, support rich configuration, support Promise
, support browser and Node.js
client . Since Vue
2.0, Youda announced that it will cancel the official recommendation vue-resource
of , and recommend it instead axios
. Now axios
it has become Vue
the first choice of most developers
characteristic
- Created from the browser
XMLHttpRequests
- from
node.js
createhttp
request - support
Promise
API - Intercept requests and responses
- Transform request data and response data
- cancel request
- Automatically convert
JSON
data - Client Support Defense
XSRF
basic use
Install
// 项目中安装
npm install axios --S
// cdn 引入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
import
import axios from 'axios'
send request
axios({
url:'xxx', // 设置请求的地址
method:"GET", // 设置请求方法
params:{
// get请求使用params进行参数凭借,如果是post请求用data
type: '',
page: 1
}
}).then(res => {
// res为后端返回的数据
console.log(res);
})
concurrent requestsaxios.all([])
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (res1, res2) {
// res1第一个请求的返回的内容,res2第二个请求返回的内容
// 两个请求都执行完成才会执行
}));
2. Why package
axios
The API is very friendly, you can easily use it directly in your project.
However, as the scale of the project increases, every time HTTP
a request is initiated, operations such as setting the timeout period, setting the request header, judging which request address to use according to the project environment, error handling, etc., need to be written again
This kind of duplication of work not only wastes time, but also makes the code redundant and difficult to maintain. In order to improve our code quality, we should re-encapsulate it in the project axios
before using
for example:
axios('http://localhost:3000/data', {
// 配置代码
method: 'GET',
timeout: 1000,
withCredentials: true,
headers: {
'Content-Type': 'application/json',
Authorization: 'xxx',
},
transformRequest: [function (data, headers) {
return data;
}],
// 其他请求配置...
})
.then((data) => {
// todo: 真正业务逻辑代码
console.log(data);
}, (err) => {
// 错误处理代码
if (err.response.status === 401) {
// handle authorization error
}
if (err.response.status === 403) {
// handle server forbidden error
}
// 其他错误处理.....
console.log(err);
});
If each page sends a similar request, it will be too cumbersome to write a bunch of configuration and error handling
At this time, we need to axios
carry out secondary packaging to make it more convenient to use
3. How to package
While encapsulating, you need to negotiate some agreements with the backend, request header, status code, request timeout...
Set the interface request prefix: according to different development, test, and production environments, the prefix needs to be distinguished
Request header: To implement some specific services, some parameters must be carried before the request can be made (for example: membership business)
Status code: According to the difference returned by the interface status
, different services are executed, which needs to be agreed with the backend
Request method: re-encapsulate according to methods such as get
, etc., which is more convenient to usepost
Request Interceptor: Determine which requests can be accessed according to the request header settings of the request
Response interceptor: This block is to judge and execute different businesses according to the status code returned by the backend`
Set the interface request prefix
Use node
environment variables to make judgments to distinguish development, testing, and production environments
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = 'http://prod.xxx.com'
}
When debugging locally, you also need to vue.config.js
configure proxy forwarding in the file devServer
to achieve cross-domain
devServer: {
proxy: {
'/proxyApi': {
target: 'http://dev.xxx.com',
changeOrigin: true,
pathRewrite: {
'/proxyApi': ''
}
}
}
}
Set request headers and timeouts
In most cases, the request headers are fixed, and only in a few cases, some special request headers are required. Here, the universal request headers are used as the basic configuration. When a special request header is required, the special request header is passed in as a parameter to override the basic configuration
const service = axios.create({
...
timeout: 30000, // 请求 30s 超时
headers: {
get: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
},
post: {
'Content-Type': 'application/json;charset=utf-8'
// 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
}
},
})
Package request method
First introduce the encapsulated method, and re-encapsulate it into a method in the interface to be called to expose it
// get 请求
export function httpGet({
url,
params = {
}
}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params
}).then((res) => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
}
// post
// post请求
export function httpPost({
url,
data = {
},
params = {
}
}) {
return new Promise((resolve, reject) => {
axios({
url,
method: 'post',
transformRequest: [function (data) {
let ret = ''
for (let it in data) {
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
return ret
}],
// 发送的数据
data,
// url参数
params
}).then(res => {
resolve(res.data)
})
})
}
Put the encapsulated method in a api.js
file
import {
httpGet, httpPost } from './http'
export const getorglist = (params = {
}) => httpGet({
url: 'apps/api/org/list', params })
can be called directly from the page
// .vue
import {
getorglist } from '@/assets/js/api'
getorglist({
id: 200 }).then(res => {
console.log(res)
})
In this way, unified management can api
be achieved, and future maintenance and modification only need to api.js
be performed on the file.
request interceptor
The request interceptor can add a token to each request, and it is easy to maintain after unified processing
// 请求拦截器
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断是否存在token
// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
})
response interceptor
The response interceptor can perform a layer of operations after receiving the response, such as judging the login status and authorization based on the status code
// 响应拦截器
axios.interceptors.response.use(response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
if (response.status === 200) {
if (response.data.code === 511) {
// 未授权调取授权接口
} else if (response.data.code === 510) {
// 未登录跳转登录页
} else {
return Promise.resolve(response)
}
} else {
return Promise.reject(response)
}
}, error => {
// 我们可以在这里对异常状态作统一处理
if (error.response.status) {
// 处理请求失败的情况
// 对不同返回码对相应处理
return Promise.reject(error.response)
}
})
summary
- Encapsulation is a very meaningful means in programming. Simple
axios
encapsulation allows us to appreciate its charm - Encapsulation
axios
There is no absolute standard, as long as your encapsulation can meet your project requirements and is easy to use, it is a good encapsulation solution
reference article
- https://www.html.cn/qa/vue-js/20544.html
- https://juejin.cn/post/6844904033782611976
- https://juejin.cn/post/6844903801451708429