Appearance
下面是常用的 axios 方法和属性
类别 | 方法/属性 | 描述 |
---|---|---|
基本方法 | axios.request(config) | 用于发起请求 |
axios.get(url[, config]) | 发起 GET 请求 | |
axios.delete(url[, config]) | 发起 DELETE 请求 | |
axios.head(url[, config]) | 发起 HEAD 请求 | |
axios.post(url[, data[, config]]) | 发起 POST 请求 | |
axios.put(url[, data[, config]]) | 发起 PUT 请求 | |
axios.patch(url[, data[, config]]) | 发起 PATCH 请求 | |
并发处理 | axios.all(iterable) | 处理多个并发请求 ,随着 ES6 和后续版本中 Promise.all() 的普及,许多开发者发现直接使用 Promise.all() 更为直观和方便 |
axios.spread(callback) | 分割并发响应的结果 ,随着 ES6 和后续版本中 Promise.all() 的普及,许多开发者发现直接使用 Promise.all() 更为直观和方便 | |
实例 | axios.create([config]) | 创建一个新的 axios 实例 |
拦截器 | axios.interceptors.request.use(success[, error]) | 添加请求拦截器 |
axios.interceptors.response.use(success[, error]) | 添加响应拦截器 | |
默认配置 | axios.defaults | 查看或修改默认配置 |
取消请求 | axios.CancelToken | 创建取消令牌 |
axios.isCancel(value) | 判断值是否为取消的请求 | |
响应结构 | data, status, statusText, headers, config, request | 响应的各个部分 |
默认值 | axios.defaults.baseURL | 设置默认的 baseURL |
axios.defaults.timeout | 设置请求的超时时间 | |
axios.defaults.headers | 设置默认的请求头 |
- config 属性介绍
属性 | 描述 | 示例 |
---|---|---|
url | 用于请求的服务器URL | /user |
method | 创建请求时使用的方法 | get |
baseURL | 将自动加在 url 前面的基础URL | https://some-domain.com/api/ |
transformRequest | 在向服务器发送前,修改请求数据的函数 | [function (data, headers) { return data; }] |
transformResponse | 在传递给 then/catch 前,允许修改响应数据的函数 | [function (data) { return data; }] |
headers | 自定义请求头 | {'X-Requested-With': 'XMLHttpRequest'} |
params | 与请求一起发送的URL参数 | { ID: 12345 } |
paramsSerializer | 用于序列化params 的函数 | function (params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) } |
data | 作为请求体被发送的数据 (示例1) | { firstName: 'Fred' } |
data | 作为请求体被发送的数据 (示例2) | 'Country=Brasil&City=Belo Horizonte' |
timeout | 指定请求超时的毫秒数 | 1000 |
withCredentials | 表示跨域请求时是否需要使用凭证 | false |
adapter | 允许自定义处理请求的函数 | function (config) { /* ... */ } |
auth | HTTP Basic Auth | { username: 'janedoe', password: 's00pers3cret' } |
responseType | 表示浏览器将要响应的数据类型 | json |
responseEncoding | 表示用于解码响应的编码 (Node.js 专属) | utf8 |
xsrfCookieName | xsrf token 的值,被用作 cookie 的名称 | XSRF-TOKEN |
xsrfHeaderName | 带有 xsrf token 值的http 请求头名称 | X-XSRF-TOKEN |
onUploadProgress | 允许为上传处理进度事件的函数 | function (progressEvent) { /* ... */ } |
onDownloadProgress | 允许为下载处理进度事件的函数 | function (progressEvent) { /* ... */ } |
maxContentLength | 定义了node.js中允许的HTTP响应内容的最大字节数 | 2000 |
maxBodyLength | 定义允许的http请求内容的最大字节数 (仅Node) | 2000 |
validateStatus | 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise的函数 | function (status) { return status >= 200 && status < 300; } |
maxRedirects | 定义了在node.js中要遵循的最大重定向数 | 5 |
socketPath | 在node.js中使用的UNIX套接字 | null |
httpAgent & httpsAgent | 在node.js中用于执行http和https请求的自定义代理 | new http.Agent({ keepAlive: true }) |
proxy | 定义了代理服务器的配置 | { protocol: 'https', host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } } |
cancelToken | 取消请求的token | new CancelToken(function (cancel) { }) |
decompress | 指示是否自动解压缩响应体 | true |
简单封装进一步了解
- 首先,我们引入了
axios
库。 - 使用
axios.create
方法创建了一个axios实例,并为其设置了基础URL和请求超时时间。 - 使用
interceptors.request.use
方法添加了请求拦截器,可以在发送请求之前进行一些操作,例如添加token。
js
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
- 使用
interceptors.response.use
方法添加了响应拦截器,可以对返回的响应数据进行处理,例如根据响应码进行不同的操作。
成功的回调:当请求成功返回(即HTTP状态码为2xx)时,这个函数会被调用。这个函数接受一个参数,即服务器的响应对象,并且必须返回一个值或Promise。返回的值将作为请求的响应传递给后续的
then
方法。错误的回调:axios将所有在范围外的状态码(即小于200或大于299)视为错误,当请求返回一个错误响应(例如HTTP状态码为4xx或5xx)或由于其他原因(例如网络问题)导致请求失败时,这个函数会被调用。这个函数接受一个错误对象作为参数,并且必须返回一个错误或Promise。返回的错误将被传递给后续的 catch 方法。
js
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
- 设置指定错误状态码使用
axios.defaults.validateStatus
配置选项来自定义这个行为
js
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的实现
}
案例一
导出了这个axios实例,这样在其他地方就可以直接使用这个已经配置好的axios实例进行请求。
javascript
// 引入axios库
import axios from 'axios';
// 创建axios实例
const instance = axios.create({
baseURL: 'https://api.example.com', // 基础URL,可以根据实际情况进行修改
timeout: 5000, // 请求超时时间
});
// 请求拦截器
instance.interceptors.request.use(
config => {
// 在发送请求之前做些什么,例如添加token
// config.headers['Authorization'] = 'Bearer ' + token;
return config;
},
error => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
response => {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response.data.data;
},
error => {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
export default instance;
案例二
一些其他详细封装
js
/*
axios二次封装:把每一次基于axios发送请求的公共部分进行提取
+ axios.defaults.xxx
+ axios.interceptors.request/response 拦截器
*/
import axios from 'axios';
import qs from 'qs';
const isPlainObject = function isPlainObject (obj) {
let proto, Ctor;
if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
proto = Object.getPrototypeOf(obj);
if (!proto) return true;
Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
return typeof Ctor === "function" && Ctor === Object;
};
// 请求URL地址没有加前缀,则默认把BASE-URL加上;如果请求时候,自己设置前缀了,则以自己写的为主;
// 真实开发的时候,我们项目有各种不同的环境「开发、测试、灰度、生产」:我们需要针对不同的环境,有不同的BASE-URL
// 1)在运行编译的时候,设置环境变量
// + 安装cross-env插件 $ npm i cross-env
// + package.json的scripts中做处理
// 开发环境 serve:"cross-env NODE_ENV=development vue-cli-service serve",
// 生产环境 build:"cross-env NODE_ENV=production vue-cli-service build"
// 2)在代码中获取环境变量的值,根据不同值,设置不同的BASE-URL
let env = process.env.NODE_ENV || 'development',
baseURL = '';
switch (env) {
case 'development':
baseURL = 'http://127.0.0.1:9999';
break;
case 'production':
baseURL = 'http://api';
break;
}
axios.defaults.baseURL = baseURL;
// 一些可以提取的小东西:超时时间 & CORS跨域中是否允许携带资源凭证(例如:cookie)
// + 客户端的withCredentials:true,那么服务器端也要设置为允许
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
// 请求参数 拦截重新拼接的案例
// POST系列请求中:请求主体中传递给服务器的信息,项目要求需要是URLENCODED格式;(强行无论请求方式是什么都是URLENCODED格式)
// 当代浏览器中,我们请求主体传递给服务器的格式是啥,浏览器会自动在请求头中,更新Content-Type!
axios.defaults.transformRequest = data => {
// 只有我们写的DATA是一个纯粹的对象,才需要按需求处理
if (isPlainObject(data)) data = qs.stringify(data);
return data;
};
// 自己规定,服务器返回的状态码,值是多少算是请求成功
// 成功:服务器正常返回响应信息,且返回的HTTP状态码是经过validateStatus校验通过的
// 失败:
// + 服务器有返回的信息,但是返回的HTTP状态码并没有经过validateStatus的校验
// + 请求超时或者请求中断 reason.code==='ECONNABORTED'
// + 服务器没有返回任何信息「可能是断网了」
// + ...
axios.defaults.validateStatus = status => {
return status >= 200 && status < 400;
};
// 请求拦截器:在axios内部已经把config的那些配置项处理差不多了,并且打算按照配置项,向服务器发送请求之前进行拦截;
// 拦截目的是把配置项中的一些信息再改改!
axios.interceptors.request.use(config => {
// 常见需求:在每一次发送请求的时候,通过请求头把token信息传递给服务器
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = token;
}
return config;
});
// 响应拦截器:onfulfilled/onrejected,发生在请求成功/失败,在业务层具体.then/catch之前进行拦截处理
axios.interceptors.response.use(response => {
// 请求成功:一般我们会返回响应主体信息
return response.data;
}, reason => {
// 请求失败:一般我们会做统一的错误提示
if (reason && reason.response) {
let response = reason.response;
// 有响应信息,但是状态码不对,我们根据不同的状态码做不同的提示
switch (response.status) {
case 400:
// ...
break;
case 401:
// ...
break;
case 404:
// ...
break;
}
} else {
if (reason && reason.code === 'ECONNABORTED') {
// 请求超时或者中断
}
if (!navigator.onLine) {
// 断网了
}
}
return Promise.reject(reason);
});
export default axios;