Axios
axios 是什么
Axios
是一个基于promise
的HTTP
库,可以用在浏览器和node.js
中。前端最流行的ajax
请求库,
react/vue
官方都推荐使用axios
发ajax
请求
axios 特点
- 基于
promise
的异步ajax
请求库,支持promise
所有的API
- 浏览器端/
node
端都可以使用,浏览器中创建XMLHttpRequests
- 支持请求/响应拦截器
- 支持请求取消
- 可以转换请求数据和响应数据,并对响应回来的内容自动转换成
JSON
类型的数据 - 批量发送多个请求
- 安全性更高,客户端支持防御
XSRF
,就是让你的每个请求都带一个从cookie
中拿到的key
, 根据浏览器同源策略,假冒的网站是拿不到你cookie
中得key
的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略
全局修改axios默认配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
配置优先级
request config
> instance.defaults
> 系统默认
// 创建一个实例,这时的超时时间为系统默认的 0
var instance = axios.create();
// 通过instance.defaults重新设置超时时间为2.5s,因为优先级比系统默认高
instance.defaults.timeout = 2500;
// 通过request config重新设置超时时间为5s,因为优先级比instance.defaults和系统默认都高
instance.get('/longRequest', {
timeout: 5000
});
axios 常用语法
axios(config)
: 通用/最本质的发任意类型请求的方式axios(url[, config])
: 可以只指定 url 发 get 请求axios.request(config)
: 等同于 axios(config)axios.get(url[, config])
: 发 get 请求- 直接在url中拼接数据
axios({ url: "http://123.207.32.32:8000/home/multidata?aaa=1&type=2" }).then(res => console.log(res))
- config中配置params属性
axios({ url: "http://123.207.32.32:8000/home/multidata", params: { aaa: 1, type: 2 } }).then(res => console.log(res)).catch(err => console.log(err))
axios.delete(url[, config])
: 发 delete 请求axios.post(url[, data, config])
: 发 post 请求
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
axios.put(url[, data, config])
: 发 put 请求axios.defaults.xxx
: 请求的默认全局配置axios.interceptors.request.use()
: 添加请求拦截器axios.interceptors.response.use()
: 添加响应拦截器axios.create([config])
: 创建一个新的 axios(它没有下面的功能)axios.Cancel()
: 用于创建取消请求的错误对象axios.CancelToken()
: 用于创建取消请求的 token 对象axios.isCancel()
: 是否是一个取消请求的错误axios.all(promises)
: 用于批量执行多个异步请求
axios.all([]);//传入一个数组,数组元素都是一个axios网络请求
axios.all([
axios({
url:"http://123.207.32.32:8000/home/data"
}),
axios({
url:"http://123.207.32.32:8000/home/multidata"
})
]).then(res=>console.log(res))
res是一个数组,两个请求结果返回的数据组成的数组
axios.spread()
: 用来指定接收所有成功数据的回调函数的方法
拦截器
// 添加一个请求拦截器
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
// 添加一个响应拦截器
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
取消请求
- 可以使用
CancelToken.source
工厂方法创建cancel token
,像这样:
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
- 还可以通过传递一个
executor
函数到CancelToken
的构造函数来创建cancel token
:
var CancelToken = axios.CancelToken;
var cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// 取消请求
cancel();
封装
- 给不同环境配置不同请求地址 根据
process.env.NODE_ENV
配置不同的baseURL
,使项目只需执行相应打包命令,就可以在不同环境中自动切换请求主机地址
const getBaseUrl = (env) => {
let base = {
production: '/',
development: 'http://localhost:3000',
test: 'http://localhost:3001',
}[env];
if (!base) {
base = '/';
}
return base;
};
class NewAxios {
constructor() {
this.baseURL = getBaseUrl(process.env.NODE_ENV);
}
}
timeout
:超时时间widthCredentials
:允许携带凭证
完整封装后的代码
import axios from 'axios';
const getBaseUrl = (env) => {
let base = {
production: '/',
development: 'http://localhost:3000',
test: 'http://localhost:3001',
}[env];
if (!base) {
base = '/';
}
return base;
};
class NewAxios {
constructor() {
this.baseURL = getBaseUrl(process.env.NODE_ENV);
this.timeout = 10000;
this.withCredentials = true;
}
setInterceptors = (instance, url) => {
instance.interceptors.request.use((config) => {
// 在这里添加loading
// 配置token
config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || '';
return config;
}, err => Promise.reject(err));
instance.interceptors.response.use((response) => {
// 在这里移除loading
// todo: 想根据业务需要,对响应结果预先处理的,都放在这里
return response;
}, (err) => {
if (err.response) { // 响应错误码处理
switch (err.response.status) {
case '403':
// todo: handler server forbidden error
break;
// todo: handler other status code
default:
break;
}
return Promise.reject(err.response);
}
if (!window.navigator.online) { // 断网处理
// todo: jump to offline page
return -1;
}
return Promise.reject(err);
});
}
request(options) {
// 每次请求都会创建新的axios实例。
const instance = axios.create();
const config = { // 将用户传过来的参数与公共配置合并。
...options,
baseURL: this.baseURL,
timeout: this.timeout,
withCredentials: this.withCredentials,
};
// 配置拦截器,支持根据不同url配置不同的拦截器。
this.setInterceptors(instance, options.url);
return instance(config); // 返回axios实例的执行结果
}
}
export default new NewAxios();
//import axios from 文件名
axios.request({url: '/data'})