axios封装
基本
import axios from 'axios'
const baseURL = process.env.NODE_ENV === 'production' ? 'https://api.995120.cn/' : 'http://api-test.995120.cn/'; // 生产 : 测试
const instance = axios.create({
baseURL: baseURL,
timeout: 10000,
});
export const get = (url, params = {}) => {
return new Promise((resolve, reject) => {
instance.get(url, { params }).then((response) => {
resolve(response.data)
}, err => {
reject(err)
})
})
}
export const post = (url, data = {}) => {
return new Promise((resolve, reject) => {
instance.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
resolve(response.data)
}, err => {
reject(err)
})
})
}
export const patch = (url, data = {}) => {
return new Promise((resolve, reject) => {
instance.patch(url, data, {
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
resolve(response.data)
}).catch(err => {
reject(err)
})
})
}
mock灵活配置
创建三个文件(index.js/ interceptor.js/ request.js)
参考自 https://mp.weixin.qq.com/s/A__ereOEdsDri6bgp-0w9g
/**
* index.js
* api地址管理
*/
export default {
login:'/user/login',
getInfo:'/user/getInfo'
}
/**
* interceptor.js
* 生成基础axios对象,并对请求和响应做处理
* 前后端约定接口返回解构规范
* {
* code:0,
* data:"成功",
* message:""
* }
*/
import axios from 'axios'
import { Message } from 'element-ui'
// 创建一个独立的axios实例
const service = axios.create({
// 设置baseUr地址,如果通过proxy跨域可直接填写base地址
baseURL: '/api',
// 定义统一的请求头部
headers: {
post: {
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
}
},
// 配置请求超时时间
timeout: 10000,
// 如果用的JSONP,可以配置此参数带上cookie凭证,如果是代理和CORS不用设置
withCredentials: true
});
// 请求拦截
service.interceptors.request.use(config => {
// 自定义header,可添加项目token
config.headers.token = 'token';
return config;
});
// 返回拦截
service.interceptors.response.use((response)=>{
// 获取接口返回结果
const res = response.data;
// code为0,直接把结果返回回去,这样前端代码就不用在获取一次data.
if(res.code === 0){
return res;
}else if(res.code === 10000){
// 10000假设是未登录状态码
Message.warning(res.message);
// 也可使用router进行跳转
window.location.href = '/#/login';
return res;
}else{
// 错误显示可在service中控制,因为某些场景我们不想要展示错误
// Message.error(res.message);
return res;
}
},()=>{
Message.error('网络请求异常,请稍后重试!');
});
export default service;
/**
* request.js
* 通过promise对axios做二次封装,针对用户端参数,做灵活配置
*/
import { Message,Loading } from 'element-ui';
import instance from './interceptor'
/**
* 核心函数,可通过它处理一切请求数据,并做横向扩展
* @param {url} 请求地址
* @param {params} 请求参数
* @param {options} 请求配置,针对当前本次请求;
* @param loading 是否显示loading
* @param mock 本次是否请求mock而非线上
* @param error 本次是否显示错误
*/
function request(url,params,options={loading:true,mock:false,error:true},method){
let loadingInstance;
// 请求前loading
if(options.loading)loadingInstance=Loading.service();
return new Promise((resolve,reject)=>{
let data = {}
// get请求使用params字段
if(method =='get')data = {params}
// post请求使用data字段
if(method =='post')data = {data:params}
// 通过mock平台可对局部接口进行mock设置
if(options.mock)url='http://www.mock.com/mock/xxxx/api';
instance({
url,
method,
...data
}).then((res)=>{
// 此处作用很大,可以扩展很多功能。
// 比如对接多个后台,数据结构不一致,可做接口适配器
// 也可对返回日期/金额/数字等统一做集中处理
if(res.status === 0){
resolve(res.data);
}else{
// 通过配置可关闭错误提示
if(options.error)Message.error(res.message);
reject(res);
}
}).catch((error)=>{
Message.error(error.message)
}).finally(()=>{
loadingInstance.close();
})
})
}
// 封装GET请求
function get(url,params,options){
return request(url,params,options,'get')
}
// 封装POST请求
function post(url,params,options){
return request(url,params,options,'post')
}
export default {
get,post
}
- 导入
// 导入插件
import request from './api/request'
// 在原型上扩展,这样不用在每个页面都导入request
Vue.prototype.request = request;
- 调用
this.request.get('/login',{userName:'admin',userPwd:'admin'}).then((res={})=>{
// 此处只接收成功数据,失败数据不返回
}).catch(()=>{
// catch 可以不要,如果想要捕获异常,就加上去
})
若依
import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_SERVER_URL,
// 超时
timeout: 100000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
if (getToken() && !isToken) {
config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof(value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.status || 200;
// 获取错误信息
const msg = errorCode[code] || errorCode['default']
if (code === 401) {
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
store.dispatch('LogOut').then(() => {
location.href = process.env.VUE_APP_BASE_API + '/index';
})
}).catch(() => {});
} else if (code === 500) {
Message({
message: msg,
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
if(null != res.data && null != res.data.success) {
if(!res.data.success) {
Message({
message: res.data.msg,
type: 'error'
})
return Promise.reject(new Error(res.data.msg))
}
return res.data
}
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service