1.axios的配置与使用
a.在src中新建apiconfig/index.js文件,引入axios并进行请求响应的封装(以登陆接口为例)
// 配置axios拦截等
import axios from 'axios'
import store from '../store/index'
// import _ from 'lodash' javascript库
import { Message, Loading } from 'element-ui'
// 初始化axios 创建axios实例
const service = axios.create({
// baseURL: 判断是开发/生产环境
baseURL: process.env.NODE_ENV === 'production' ? 'http://abc.com:8888/' : '/apis',
timeout: 5000
})
// loading
let loading = null
let requestAll = 0 // 当有多个请求时
const showLoading = function (target) {
if (!loading && requestAll === 0) {
loading = Loading.service({
target: target || 'body', // 显示的节点DOM
lock: true,
text: '加载中⭐⭐',
background: 'rgba(255, 255, 255, 0.5)'
})
}
requestAll++
}
// 关闭loading
const closeLoading = function () {
requestAll--
if (requestAll === 0) {
loading ? loading.close() : (loading = null)
}
}
// 请求拦截 用于封装请求headers等
service.interceptors.request.use(
config => {
// 拦截下来封装请求头
showLoading()
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
// 如果存在token值就添加进Authorization
if (store.state.token) {
config.headers.Authorization = store.state.token
}
// 发送请求
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截 下面具体根据实际接口配置
service.interceptors.response.use(
response => {
closeLoading()
console.log('response', response)
const res = response.data
if (res && res.code === 10000) {
return res.data// 封装好可直接返回data
} else if (res.code === 10001) {
Message({
message: res.message,
type: 'warning',
duration: 3000
})
return Promise.reject(res.message || '后端服务错误')// 因为此时是收到了后端的接口数据 Promise.reject(res)返回一个被res原因拒绝的promise对象
} else if (res.status === 403) {
Message({
message: '登录失效,请重新登录',
type: 'error',
duration: 3000
})
// 清除cookie信息
store.commit('updateToken', '')
window.location.href = '#/login'
return 1
} else {
// 处理execl
return response.data
}
},
// 登陆接口可以配合js-cookie或者localstorage进行token的保存,在未登出的情况下结合路由守卫直接进入home页
// 在后台token失效时的逻辑,此时因为cookie中有token,所以路由守卫不会拦截,还是会进入home页面,但如果在home页面请求其他接口时判断发给后台的token,如果已经失效,后台令403为登陆失效的信息,前端清除cookie与state中的token值
// 如果没有token值,则路由守卫会作出处理,直接进入login页面
error => {
closeLoading()
if (error.response.status === 403) {
} else {
}
return Promise.reject(error.response)
}
)
export default service
b.在main.js中进行全局的引入
c.在具体组件中进行调用
async loginForm () {
// 一定注意请求方式
const data = await this.axios.get('/api/login', {
params: {
name: this.ruleLogin.name,
password: this.ruleLogin.password
}
})
this.$store.commit('updateToken', data)
this.$router.push('/')
},
//post请求 this.axios.post('...',data)
//上传下载文件时,如果要求确定接口参数形式,比如responseType,形式如下所示
const data = await this.axios.get('/api/getName', {
params: this.request,
// 一定要加上这句
responseType: 'blob'
})
2.开发环境与生产环境跨域的配置
a.开发环境:使用反向代理,服务器之间不存在跨域问题,如果请求的链接不存在,则会返回本地index文件的内容。
配置目录 /config/index.js
proxyTable: {
'/apis':{//以apis开头的url才会进行接口转发
target: 'http://10.1.63.26:19080/', // 后台api
changeOrigin: true, //是否跨域
// secure: true,
pathRewrite: {
'^/apis': '' //需要rewrite的
}
}
}
或者使用浏览器中的插件
b.生产环境:需要后端开启跨域 打包之后部署到服务器要去除/apis,才能正常访问后台接口
axios的默认实例有一个baseURL的属性
axios.defaults.baseURL='/apis'
axios.get('/user') //访问/user就相当于访问 http://localhost:8080/apis/user
axios.defaults.baseURL='https://abc.com'
axios.get('/user') //访问/user就相当于访问 https://abc.com/user
//process.env.NODE_ENV用于区分是生产环境还是开发环境
//配置不同的baseURL
baseURL: process.env.NODE_ENV === 'production' ? 'http://abc.com:8888/' : '/apis'
这样配置之后,打包部署到服务器上也不用再手工去除/apis
补充:
1.存在多个请求路径
可以配置多个axios,分别在全局引入
2.可在api.js中对接口完成统一维护
//可在src下新建api.js文件夹,引入封装好的axios,然后在需要调用的地方直接引入
import axios from '../apiconfig/index';
export defalue {
//GET请求
fetchData1 = query => {
return request({
url: '/table1.json',
method: 'get',
params: query
});
};
//POST请求
fetchData2 = query => {
return request({
url: '/table2.json',
method: 'post',
data: query
});
};
//delete、put请求同get的写法
}