vue cli 3以上的版本,跨域代理不再需要放在build文件夹下,而是直接在vue.config.js中vueConfig配置devServer选项。
先上代码:
devServer: {
// development server port 8000
port: 8000,
// If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
proxy: {
'/auth': {
target: baseUrl.url('auth'),
ws: false,
secure: false,
changeOrigin: true,
// 路径重写
pathRewrite: {
"^/auth": '/api/v1/auth' // auth, 如果你的后边还有路径的话, 会自动拼接上
}
},
'/login': {
target: baseUrl.url('login'),
ws: false,
secure: false,
changeOrigin: true,
// 路径重写
pathRewrite: {
"^/login": '/api/v1/login' // 如果你的后边还有路径的话, 会自动拼接上
}
}
}
},
在proxy选项中,添加代理,有多少个服务需要代理就添加多少对象。
target: 需要代理的目标地址,一般是后端服务的ip:port。
ws:是否需要开启webSocket。
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin:设置为true, 本地就会虚拟一个服务器接收你的请求并代你发送该请求,这样就能跨域了。
pathRewrite:代理路径重写。如: '^/login‘ :表示 接口中的/login 会被替换成 /api/v1/login。 然后再加上target,完整的地址应该把是: ip:port/api/v1/login。
然后在你的axios请求中的地址应该是: /login接上你实际的业务上的请求路径。如:/login/logout,经过代理之后的地址会变成:
ip:port/api/v1/login/logout ,因为/login 被重写成了api/v1/login。
附上axios代码:
export function login (parameter) {
const params = {
'username': parameter.username,
'password': parameter.password,
'verifyCode': parameter.verifyCode
}
return axios({
url: '/login/async/login',
method: 'post',
params: params,
headers: parameter.headers
})
}
import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import { VueAxios } from './axios'
import { ACCESS_TOKEN } from '@/store/mutation-types'
// 创建 axios 实例
const service = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL, // api base_url
timeout: 20000, // 请求超时时间
withCredentials: true
})
const err = (error) => {
if (error.response) {
const data = error.response.data
const token = Vue.ls.get(ACCESS_TOKEN)
if (error.response.status === 403) {
notification.error({
message: 'Forbidden',
description: data.message
})
}
if (error.response.status === 401 && !(data.result && data.result.isLogin)) {
// notification.error({
// message: 'Unauthorized',
// description: 'Authorization verification failed'
// })
if (token) {
store.dispatch('Logout').then(() => {
setTimeout(() => {
window.location.reload()
}, 1500)
})
}
} else {
// 除了几个错误的状态码,其他错误的状态的请求结果直接反馈到请求源
return Promise.resolve(error.response.data)
}
// if (error.response.status !== 200) {
// if (error.response.data) {
// notification.error({
// message: 'request error',
// description: error.response.data.error
// })
// }
// }
}
return Promise.reject(error)
}
// 需要直接返回整个response的接口
const whiteListUrl = [
'/login/kaptcha/image'
]
// request interceptor
service.interceptors.request.use(config => {
const token = Vue.ls.get(ACCESS_TOKEN)
if (token) {
config.headers['Authorization'] = `bearer ${token}` // 让每个请求携带自定义 token 请根据实际情况自行修改
}
return config
}, err)
// response interceptor
service.interceptors.response.use((response) => {
if (whiteListUrl.includes(response.config.url)) {
return response
} else {
return response.data
}
}, err)
const installer = {
vm: {},
install (Vue) {
Vue.use(VueAxios, service)
}
}
export {
installer as VueAxios,
service as axios
}
const VueAxios = {
vm: {},
// eslint-disable-next-line no-unused-vars
install (Vue, instance) {
if (this.installed) {
return
}
this.installed = true
if (!instance) {
// eslint-disable-next-line no-console
console.error('You have to install axios')
return
}
Vue.axios = instance
Object.defineProperties(Vue.prototype, {
axios: {
get: function get () {
return instance
}
},
$http: {
get: function get () {
return instance
}
}
})
}
}
export {
VueAxios
}