Axios封装一款前端项目网络请求实用插件
前端项目开发非常经典的插件axios大家都很熟悉,它是一个Promise网络请求库,可以用于浏览器和 node.js 支持的项目中。像一直以来比较火的Vue.js开发的几乎所有项目网络请求用的都是axios。那么我们在实际的项目中,有时候为了便于维护、请求头信息统一处理、统一拦截器设置以及响应数据统一处理,需要在项目中针对axios封装一个网络请求插件。接下来就介绍一下针对以上这些输出具体的解决方案和步骤。
封装前准备(安装axios插件)
#安装前先确定node.js版本,可以前往下载对应的nodejs版本:https://nodejs.org/zh-cn/download
yarn add axios
创建一个网络请求组件(用于提供对外访问)
axios-utils.js
/**
* 能用网络请求
* @param method {'GET'|'PUT'|'POST'|'DELETE'} 请求方式
* @param url 请求相对或完整路径
* @param params 请求对象参数
* @param headers 请求头对象参数
* @param thenCall 当请求状态码返回非成功或非对象时回调,便于异常数据统一处理
* @returns {*} Promise
*/
export function axiosapi(method = "post", url = '', params = {}, headers = {}, thenCall) {
//创建axios对象实例
let instance = axios.create({
baseURL: "/api", //根url地址,这里设置的是代理地址(请看下面配置)
//在跨域请求时,这个属性特别重要。根据浏览器的同源策略,为了安全起见,浏览器会阻止跨源HTTP请求。
//通过设置 withCredentials为true,可以允许跨域请求时携带证书信息,从而绕过这个限制。
withCredentials: true,
//公共请求头信息设置
headers: {
"token": getToken(),
"version": "1.0.2"
}
});
//设置本次网络请求拦截器
instance.interceptors.request.use((config) => {
//这里处理你的请求拦截信息
return config;
}, function (error) {
return Promise.reject(error);
});
//设置本次网络请求响应拦截器
instance.interceptors.response.use((res) => {
//这里处理你的响应拦截信息
return res;
}, (error) => {
//解决请求异常时网页出现ERR_BAD_REQUEST错误导致功能不能使用情况,需要返回空的Promise对象
if (error.code === 'ERR_BAD_REQUEST') {
Promise.resolve({});
} else {
return Promise.reject(error);
}
});
return request.axiosRequest(instance, method, url, params, headers, thenCall);
}
本地代理地址配置(仅在开发时生效)
devServer: {
proxy: {
'/api/*': {
target: 'https://xxx.xxxx.com/',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}
}
},
封装axiosRequest网络请求核心组件(axios-request.js)
网络请求post请求参数梳理
if (type == "post" || type == "POST") {
//如果文件上传则创建FormData对象再将数据赋值给data,否则直接将参数赋值给data对象
if (params && headers["Content-Type"] == "multipart/form-data") {
let formData = new FormData();
for (let field in params) {
if (field == "file") {
let file = params[field];
formData.append('file', file, file.name || '');
} else {
formData.append(field, params[field]);
}
}
requestParams["data"] = formData;
} else {
requestParams["data"] = params;
}
}
对delete、put请求参数处理,自动将请求参数转成query方式,这样做在实际调用时可以不需要考虑具体传参方式
if (type == "delete" || type == "DELETE" || type == "put" || type == "PUT") {
//如果是delete和put自动将请求参数转成query方式,这样做在实际调用时可以不需要考虑具体传参方式
for (let paramsKey in params) {
url = updateQueryStringParameter(url, paramsKey, params[paramsKey]);
}
}
function updateQueryStringParameter(uri, key, value) {
let re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
let separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
} else {
return uri + separator + key + "=" + value;
}
}
axios网络统一请求
这里除了put其它都以能用的方式axios.create({})处理,因为put不支持接收axios.create({“method”:“PUT”})方式
if (type == "put" || type == "PUT") {
instance.put(url, requestParams).then(res => {
//这里处理你的返回数据,可以回调抛出去,下面给出完整示例中带有数据响应处理handleResult
// that.handleResult(true, res, resolve, reject, thenCall);
}).catch(res => {
//这里处理你的异常数据,可以回调抛出去,下面给出完整示例中带有数据响应处理handleResult
// that.handleResult(false, res, resolve, reject, thenCall);
});
} else {
requestParams["method"] = type;
requestParams["url"] = url;
instance(requestParams).then(res => {
//这里处理你的返回数据,可以回调抛出去,下面给出完整示例中带有数据响应处理handleResult
// that.handleResult(true, res, resolve, reject, thenCall);
}).catch(res => {
//这里处理你的异常数据,可以回调抛出去,下面给出完整示例中带有数据响应处理handleResult
// that.handleResult(false, res, resolve, reject, thenCall);
});
}
请求插件axios-request.js完整代码
function updateQueryStringParameter(uri, key, value) {
let re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
let separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
} else {
return uri + separator + key + "=" + value;
}
}
export default {
request: function (axiosInstance, type = "", url = "", headers = {}, params = {}, requestHandle, thenCall) {
if (type == "post" || type == "POST") {
//当post请求时以json方式提交数据
if (!headers["Content-Type"]) {
headers["Content-Type"] = "application/json;charset=utf-8";
}
}
//将请求包装一个Promise立即返回
return new Promise((resolve, reject) => {
if (requestHandle) {
requestHandle(axiosInstance, url, params, headers, resolve, reject, thenCall);
}
});
},
axiosRequest: function (axiosInstance, type = '', url = '', params = {}, headers = {}, thenCall) {
let that = this;
return that.request(axiosInstance, type, url, headers, params, function (instance, url, params, headers, resolve, reject, thenCall) {
let requestParams = {
headers: headers
};
if (type == "post" || type == "POST") {
//如果文件上传则创建FormData对象再将数据赋值给data,否则直接将参数赋值给data对象
if (params && headers["Content-Type"] == "multipart/form-data") {
let formData = new FormData();
for (let field in params) {
if (field == "file") {
let file = params[field];
formData.append('file', file, file.name || '');
} else {
formData.append(field, params[field]);
}
}
requestParams["data"] = formData;
} else {
requestParams["data"] = params;
}
} else if (type == "delete" || type == "DELETE" || type == "put" || type == "PUT") {
//如果是delete和put自动将请求参数转成query方式,这样做在实际调用时可以不需要考虑具体传参方式
for (let paramsKey in params) {
url = updateQueryStringParameter(url, paramsKey, params[paramsKey]);
}
} else {
//否则直接将参数赋值给请求对象
requestParams["params"] = params;
}
//这里除了put其它都以能用的方式axios.create({})处理,因为put不支持接收axios.create({"method":"PUT"})方式
if (type == "put" || type == "PUT") {
instance.put(url, requestParams).then(res => {
that.handleResult(true, res, resolve, reject, thenCall);
}).catch(res => {
that.handleResult(false, res, resolve, reject, thenCall);
});
} else {
requestParams["method"] = type;
requestParams["url"] = url;
instance(requestParams).then(res => {
that.handleResult(true, res, resolve, reject, thenCall);
}).catch(res => {
that.handleResult(false, res, resolve, reject, thenCall);
});
}
}, thenCall);
}
}
设置全局拦截器
通过全局请求拦截器,可以在每个请求发送前执行一些固定的操作,比如添加认证信息(如Token)、设置请求头、统一错误处理等。这有助于减少重复代码,并保持应用程序的一致性。
import Vue from 'vue';
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
// 设置统一的url
axios.defaults.baseURL = "/api";
axios.interceptors.request.use((config) => {
// 这里可以添加公共头信息
return config;
}, function (error) {
return Promise.reject(error);
});
请求示例
await axiosapi('get', '/user/login', {
"user":"admin",
"password":"123456",
....
});
错误返回数据结构
{
"code": xxx, //请求状态码
"msg": "请求状态消息"
}
成功返回数据结构
{
"code": 0, //0-成功
"msg": "success",
"data":{xxx} //响应数据信息
}
哦了,感谢你看到这里也请动动您的鼠标和小手关注一下我吧,同时也期待您在评论区提出建议,可以使我创作更优质的内容。
原文地址:https://blog.csdn.net/smart_ljh/article/details/145216840
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!