import axios from "axios";
const storage = require('@/utils/storage')
import { Toast } from 'vant'; //vant的消息提示,可以不用
//请求超时时间
axios.defaults.timeout = 20000;
const ua = 'h5;'
/**
* Promise构造函数接受一个函数作为参数,其中该参数又接受两个函数作为它自身的参数,分别是resolve和reject(也可以起其它的名字)
* new Promise()返回一个promise对象,该对象共有三种状态:进行中、已完成和失败,回调函数的调用是根据对象的状态来完成的;该对象的原型上拥有then和catch等方法。
* resolve方法的作用是把promise对象的状态从进行中变成已完成,同时可以向resolve方法传入参数,这个参数会在将来被promise对象的then方法获取,而reject方法也是同样的道理,只不过是把promise对象状态变成失败,同时传入的参数会被catch方法获取而已
* 延伸至axios:
因为axios是基于promise的,因此axios异步请求也返回一个promise对象,所以有axios().then()这样的写法,这说明axios本身已经对异步请求的过程做了封装,若请求成功则传递响应内容给then方法,否则传递给catch方法。
*/
/**
* 'content-type' : "application/json"
* form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
* 'content-type': 'application/x-www-form-urlencoded'
* 需要在表单中进行文件上传时,就需要使用该格式
* 'content-type' : 'multipart/form-data'
*/
//post 请求头
axios.defaults.headers.post['Content-Type'] = 'application/json'
/**
* 请求拦截器
* 作用:在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装
* use(两个参数)
axios.interceptors.request.use(config => {
// 在发送请求前要做的事儿
...
return config
}, err => {
// 在请求错误时要做的事儿
...
// 该返回的数据则是axios.catch(err)中接收的数据
return Promise.reject(err)
})
*/
//请求拦截器
axios.interceptors.request.use(
config => {
//每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
const access_token = storage.getSyncWithExpire('session').access_token;
//判断是否存在access_token,存在的话,每个http header都加上access_token
if (access_token) {
config.headers.AccessToken = access_token;
}
Toast.loading({
message: '加载中...',
forbidClick: true,
})
return config
},
error=>{
return Promise.error(error);
}
)
/**
* 响应拦截器
*作用:在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。
// use(两个参数)
axios.interceptors.reponse.use(res => {
// 请求成功对响应数据做处理
...
// 该返回的数据则是axios.then(res)中接收的数据
return res
}, err => {
// 在请求错误时要做的事儿
...
// 该返回的数据则是axios.catch(err)中接收的数据
return Promise.reject(err)
*/
//响应拦截器
axios.interceptors.response.use(
res=>{
Toast.clear();
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是200的情况
error => {
return httpFail(error.response)
}
)
/**
* location和history
* Location
Location.href 返回整个当前url,若对其赋值:location.href="http://www.sina.com.cn"则跳转其url
location.host 返回域名和端口号,如:www.sina.com.cn:80
lcation.hostname 返回域名
location.port 返回端口
location.pathname 返回域名后第一个斜框后的字符串
location.hash 跳到本页的某个锚
location.search 取url?后的部分
* History
history.back() 等同于按浏览器的后退按钮
history.forward() 等同于按浏览器的前进按钮
history.current 指当前的url(等同于location.href), 在历史中的索引位置总为 0
history.go(-2)或 history.go("任意.html") 向前或向后移动, 或查找字符串标明的最新url
*/
/**
* 动态设置url参数
* 设置url参数
let path = this.$router.history.current.path;
this.$router.push({ path, query: {key1:value1, key2: value2} });
* 获取url参数
const urlParams = this.$route.query;
*/
export function httpFail (res) {
// 100105(需要验证手机)错误时清空缓存中的手机号
// if (res.data.code == 100105) {
// var userInfo = storage.getSyncWithExpire('user_info')
// if(userInfo!= null && userInfo != ''){
// userInfo.phone = null
// storage.setSyncWithExpire('user_info', userInfo)
// }
// }
if (res.status == 401) {
// 获取当前页面
var currentPage = router.history.current.path;
if (res.data.code == 100400) {
// 100400 错误 pages/index/index 页面做特例处理,其他页面不执行 fail
//删掉session缓存 store上 reLogin 设为true 如果上一个页面不是首页就跳回首页重新登录 是首页特例处理
console.log(res.data.code)
storage.delSync('session')
store.commit('set_reLogin',true)
if (currentPage != '/') {
console.log('不是首页')
router.replace({
path:'/',
query:{
refresh:'refresh'
}
})
// router.go()
} else {
return Promise.reject(res)
}
} else if (currentPage == "/") {
console.log('这是首页')
res.data = res.data || {}
return Promise.reject(res)
} else {
// messageModal.errorToast('小程序错误', 1000)
localStorage.clear() // 清除所有缓存
setTimeout(() => {
router.replace({
path:'/',
query:{
refresh:'refresh'
}
})
// router.go()
}, 1000)
}
} else if (res.status == 400 && res.data.code == 100105) {
if (store.state.checkPhonePage.includes(currentPage)) {
router.replace({path:'/mine/phone'})
console.log('需要绑定手机号')
// router.replace({path:'/'})
} else {
res.data = res.data || {}
return Promise.reject(res)
}
} else {
res.data = res.data || {}
return Promise.reject(res)
}
}
export function get(url, params={}) {
params.ua = ua
return new Promise((resolve, reject) => {
axios.get(url,{
params: params,
})
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
if(err.status == 400 && err.data.code == 100105){
// Toast.fail('未绑定手机号');
Toast.clear()
}else{
Toast.fail('get请求错误');
}
})
});
}
export function post(url, params={}) {
params.ua = ua
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
if(err.status == 400 && err.data.code == 100105){
// Toast.fail('未绑定手机号');
Toast.clear()
}else{
Toast.fail('post请求错误');
}
})
});
}
export function deletes(url, params={}) {
params.ua = ua
return new Promise((resolve, reject) => {
axios.delete(url, {
data: params
}).then(res => {
resolve(res.data);
}).catch(err => {
reject(err.data);
})
})
}
export function put(url, params={}) {
params.ua = ua
return new Promise((resolve, reject) => {
axios.put(url, params).then(res => {
resolve(res);
}).catch(err => {
reject(err);
})
})
}
export default axios;
vue h5项目axios封装
于 2022-09-23 14:49:54 首次发布