import axios from 'axios'
// import qs from 'qs'
import store from '@/store'
import router from '@/router'
import { Message } from 'element-ui'
import config from '@/static/config.json'
// isSTip:操作成功的提示
// isFTip:操作失败的提示
// isDownload:是否下载文件
// 1.疑问:为什么请求一次接口,拦截器会拦截3次,甚至6次
// 回答拦截器只能创建一次,不然多次执行,就会创建多个拦截器。
// 导致上面问题。解决办法,拦截器不能写在多次执行的函数里面
axios.interceptors.request.use(
config => {
//请求头增加token
if (store.state.token) {
config.headers.Authorization = `${store.state.token}`
}
//如果后台要求的数据格式是form表单提交数据,需要用qs转数据。
//axios默认使用json格式传给后台。
if(config.headers.contentType=="application/x-www-form-urlencoded"){
config.data = qs(config.data)
}
return config
},
error => {
Promise.reject(error)
}
)
// 2.疑问:公共处理写在响应拦截器中和axios.then().catch()中写有什么区别?
// 请求失败的拦截,一般是不会触发,也不会在这里面写公共处理。只会把错误信息Promise.reject(err)出去
// 响应失败的拦截,一般服务异常情况:1.404,500会在这里拦截到,2.请求ip服务连接失败,也会在这拦截到。
// 请求失败的拦截,响应失败的拦截,最终都会在axios.catch()能捕获到。
// 3.疑问:请求成功的处理,在axios.then()中处理和在响应拦截器成功的回调中处理,有啥区别?
// 答:3.1.如果页面中需要做一些公共处理,比如下载文件操作,是否提示操作成功的提示,或者操作失败的提示。最好在axios.then中来添加执行操作。
axios.interceptors.response.use(
response => {
// 1.处理返回的数据格式。(暂不处理)//有可能后台返回的数据格式不是前端能用的,比如有些后台会返回json字符串,那么就需要在这处理数据。
return response
},
error => {
return Promise.reject(error)
}
)
function downloadFile(res){
var blob = res.data;
// FileReader主要用于将文件内容读入内存
var reader = new FileReader();
reader.readAsDataURL(blob);
// onload当读取操作成功完成时调用
reader.onload = function(e) {
var a = document.createElement('a');
// 获取文件名fileName
var fileName = res.headers["content-disposition"].split("=");
fileName = fileName[fileName.length - 1];
fileName = fileName.replace(/"/g, "");
a.download = fileName;
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
}
const service = function(configData){
return new Promise((reslove, reject)=>{
axios({
baseURL: process.env.BASE_API ? process.env.BASE_API : config.appBaseUrl, // api的base_url
timeout: 1000 * 60 * 2, // request timeout
withCredentials: false,
data: configData.data,
method: configData.method,
url: configData.url,
headers: configData.headers,//configData.headers传进来是{}对象。
responseType: configData.responseType?configData.responseType:'json'
}).then((res)=>{
// 1.code==100001,与403001,鉴权失效,跳转到登录页。
const code = response.data.code
if(code==100001){
router.push('/sign')
}else if(code==403001){
router.push('/sign')
}
// 2.是否操作成功或者失败的提示信息。
if(configData.isFTip){
Message({
message: res.message,
type: 'error',
duration: 1 * 1000
})
}
if(configData.isSTip){
Message({
message: res.message,
type: 'success',
duration: 1 * 1000
})
}
// 1.文件下载
if(configData.isDownload){
downloadFile(res)
}
reslove(res)
}).catch((err)=>{
Message({
message: '服务异常!',
type: 'error',
duration: 3 * 1000
})
reject(err)
})
})
}
export default service
//1.这个文件返回一个函数给页面使用,调用这个函数,会直接调axios,他返回的是一个promise对象。这样写,相比较直接返回出去是个axios对象的好处是,可扩展性强。能在axios中再加入公共处理。
//2.如果像恒生本部的封装写法,返回出去的是个axios对象,页面中调用接口,传的参数会直接合并到axios的config中。
// 3.后台返给前端的数据是否需要处理:是html,或者文档流,或者是json字符串格式,或者是普通的js对象。
// 4.(在路由拦截器里面也要做拦截,如果缓存中没有用户信息,或者token,也要跳转到登录页)
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交