在开始讲解前,先了解一下为什么会失效;在项目中,会遇到一个问题, 就是使用webpack
的时候,使用代理,可在开发环境中使用;但是在编译打包过后,前端页面就变成了单独的静态资源,而webpack的devServer
被抽离了出去,这是和我们的代理实际上是没有应用的
简单说就是 webpack.proxy 不会一起打包到build文件或者dist文件。
我们先来看看如何使用webpack的代理:↓
这里的例子是使用CRA crate react app
的例子,(这个其实无论在vue或者其他的库或者框架都一样,只要是webpack)
const CracoLessPlugin = require('craco-less');
const path = require('path')
module.exports = {
port: 9527,
devServer: {
'proxy': {
'/307984': {
target: 'http://rap2api.taobao.org/app/mock', // 代理地址的路径
changeOrigin: true, // 替换
},
'/': {
target: 'http://47.108.***.***:22002',// 代理地址的路径
changeOrigin: true, // 替换
pathRewrite: { // 重定向,路径重写
'^/': '', // ^首匹配 重写过后 http://47.108.***.***:22002(重写内容)/*****
},
},
},
},
};
在这里代理了两个地址, 一个是mock的地址,一个是测试服的地址,这是一个简单的例子,但是这种会面临一个问题,生产环境这不会生效,需要后端配合处理。但是其实也可以处理
解决办法:
这里用的是axios, 既然不达不到我们想要的效果那就自己写一个代理,配合
.env
来使用
import axios from 'axios';
import {message as Massage} from 'antd'
import { store } from '../store'
const service = axios.create({
// baseURL: process.env.REACT_APP_BASE_URL,
timeout: 30000,
})
// 代理配置 键做匹配项,用.env 来区分开发还是生产环境
let proxyConfig = {
'/307984': {
target: process.env.REACT_APP_ENV === 'production' 'http://rap2api.taobao.org/app/mock' : 'http://rap2api.taobao.org/app/mock',
},
'/': {
target: process.env.REACT_APP_ENV === 'production' 'https://****admin.***ap.com/api' : 'http://47.108.***.173:22002',
},
}
//定义代理
function beforeService(obj) {
let handel = {
get: (IsTarget, property, receiver) => {
// IsTarget 目标对象, property 属性, receiver 代理对象, 这里是对url做出针对处理
if (property === 'url') {
for (const key in proxyConfig) {
if ((IsTarget.url).slice(0, key.length) === key) {
return proxyConfig[key].target + IsTarget.url
}
}
} else {
return IsTarget[property]
}
},
}
// new Proxy(target目标对象, handel处理对象)
let proxy = new Proxy(obj, handel)
return service(proxy)
}
// 请求拦截
service.interceptors.request.use(function(config) {
const token = store.getState().user.tokenHead + store.getState().user.token
config.headers['Authorization'] = token
return config
})
// 响应拦截
service.interceptors.response.use(function(response) {
if (response.status >= 200 && response.status <= 300) {
let { message, data, code} = response.data
if (code === 200) { // 成功data数据
return response.data
}
if (message) {
Massage.info(message)
}
}
// 错误提示
const error = new Error('异常:' + message)
Massage.error(message);
return Promise.reject(error)
}, function(error) {
return Promise.reject(error);
})
export default beforeService // 开启代理
// export default service // 常规axios
在这个例子中定义了一个 beforeService
的函数,这里用到了我们的代理,具体可以看代码,有注释;思路是,我们在请求之前,传入url的时候,这个时候来根据路径做出匹配处理,最后再返回回去