Vue项目中封装axios请求方法(包括请求拦截)
本篇文章将对项目中如何封装axios常用的请求方法进行介绍,其中包括最容易出问题的post请求的解释,包括一些请求格式和参数格式不一致问题的解决;通用配置这些配置是在axios官方文档中没有列出来的,主要是post方法的内容类型的定义,不配置的话经常会出现请求提交失败或者数据没有正常提交的问题,这些一般都是前后端采用的post的数据格式不一致导致的。axios.defaults.timeo...
本篇文章将对项目中如何封装axios常用的请求方法进行介绍,其中包括最容易出问题的post请求的解释,包括一些请求格式和参数格式不一致问题的解决;
通用配置
这些配置是在axios
官方文档中没有列出来的,主要是post
方法的内容类型的定义,不配置的话经常会出现请求提交失败或者数据没有正常提交的问题,这些一般都是前后端采用的post的数据格式不一致导致的。
axios.defaults.timeout = 15000; //超时响应
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // 配置请求头(推荐)
// axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8'; // 配置请求头
axios.defaults.baseURL = $core.use('http'); //确认协议和地址
axios.defaults.withCredentials = true; // axios 默认不发送cookie,需要全局设置true发送cookie
1. get请求
axios中常见的get/delete请求,也称作query请求:
一般发送请求是这么写(不推荐):
axios.get('/user?id=12345&name=user')
.then(function (res) {
console.log(res);
}).catch(function (err) {
console.log(err);
});
但是为了方便全局统一调用封装的axios,我一般采用(推荐)
axios.get('/user', { //params参数必写 , 如果没有参数传{}也可以
params: {
id: 12345,
name: user
}
})
.then(function (res) {
console.log(res);
})
.catch(function (err) {
console.log(err);
});
2. post/put/patch请求
传参方式大致用的有3种
(1) 传参格式为 formData
(全局请求头:‘Content-Type’= ‘application/x-www-form-urlencoded’)
(request的Header:‘Content-Type’= ‘multipart/form-data’)
var formData=new FormData();
formData.append('user',123456);
formData.append('pass',12345678);
axios.post("/notice",formData)
.then((res) => {return res})
.catch((err) => {return err})
(2) 传参格式为 query
形式
(全局请求头:‘Content-Type’= ‘application/x-www-form-urlencoded’)
(request的Header:‘Content-Type’= ‘application/x-www-form-urlencoded’)
第一种情况:使用$qs.stringify
import Qs from 'qs' //引入方式
Vue.prototype.$qs = Qs //全局加载
this.$qs.stringify(data); //使用方式
this.$qs.parse(data); //使用方式
var readyData=this.$qs.stringify({
id:1234,
name:user
});
axios.post("/notice",readyData)
.then((res) => {return res})
.catch((err) => {return err})
(3) 传参格式为raw
(JSON格式)
第一种情况: axios将JavaScript对象序列化为JSON
(全局请求头:‘Content-Type’= ‘application/x-www-form-urlencoded’)
(request的Header:‘Content-Type’= ‘application/json;charset=UTF-8’)
var readyData={
id:1234,
name:user
};
axios.post("/notice",readyData)
.then((res) => {return res})
.catch((err) => {return err})
第二种情况:
(全局请求头:‘Content-Type’= ‘application/json;charset=UTF-8’)
(request的Header:‘Content-Type’= ‘application/json;charset=UTF-8’)
var readyData=JSON.stringify({
id:1234,
name:user
});
axios.post("/notice",readyData)
.then((res) => {return res})
.catch((err) => {return err})
下面给出常用方法的封装,可以直接用在项目中,并列出了可能会遇到的问题解决
下面所有的提示都是基于iview
的提示控件,但是一个项目如果有多个UI库就会引起很多冲突,所以建议大家只用一个UI组件库,根据自己项目情况修改提示。
/** axios封装
* 请求拦截、相应拦截、错误统一处理
*/
// import service from 'axios'
import axios from 'axios'
import QS from 'qs'
// import { Toast } from 'vant'
import router from '@/router'
import store from '../store/index'
let serviceConfig = 'http://192.168.31.69:8080'
// const axios = service.create({
// baseURL: serviceConfig // api的base_url
// /* baseURL: "http://192.168.0.107:9090", */ // api的base_url
// })
// 环境的切换
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = serviceConfig // 'api'
// axios.defaults.baseURL = 'api'
} else if (process.env.NODE_ENV === 'debug') {
axios.defaults.baseURL = ''
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = serviceConfig
// axios.defaults.baseURL = '/api'
}
// 请求超时时间
axios.defaults.timeout = 2000
// post请求头
axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded;charset=UTF-8'
// 请求拦截器
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
config.withCredentials = true
const token = store.state.token
token && (config.headers.Authorization = token)
return config
},
error => {
return Promise.error(error)
}
)
// 响应拦截器
axios.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
// 服务器状态码不是200的情况
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath }
})
break
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
this.$Modal.info({
content: '登录过期,请重新登录',
duration: 1
})
// 清除token
localStorage.removeItem('token')
store.commit('loginSuccess', null)
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}, 1000)
break
// 404请求不存在
case 404:
this.$Modal.erro({
content: '网络请求不存在',
duration: 1
})
break
// 其他错误,直接抛出错误提示
default:
this.$Modal.erro({
content: error.response.data.message,
duration: 1.5
})
}
return Promise.reject(error.response)
}
}
)
/**
* get方法,对应get请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export const get = (url, ...params) => {
return new Promise((resolve, reject) => {
axios
.get(url, {
params: params
})
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export const post = (url, ...params) => {
return new Promise((resolve, reject) => {
axios //QS.stringify(params)关于这个函数会输出什么结果大家可以自行尝试一下,结果会让你惊喜,也可以自己单独传一个对象进去测试一下
.post(url, QS.stringify(...params))
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
/**
* delet方法,对应delett请求
* @param {String} url [请求的url地址]
* delete关键字会和vue系统关键字冲突,所以这里用delet代替
* delete用于删除,参数一般带在url
*/
export const delet = url => {
return new Promise((resolve, reject) => {
axios
.delete(url)
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
/**
* patch方法,对应patch请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
* 这里根据需求适应了formdata的格式,也可以跟post用一样的封装
*/
export const patch = (url, params) => {
// 将数据转换为formData格式
// 正常情况下可以直接使用参数对象进行patch,如果出错可以尝试转换form Data
var formData = new FormData()
formData.append('username', params.username)
formData.append('password', params.password)
return new Promise((resolve, reject) => {
axios
.patch(url, formData)
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err.data)
})
})
}
更多推荐
所有评论(0)