在Vue.js项目中,为了在开发环境下解决跨域问题,我们可以利用 vue.config.js
文件中的 devServer.proxy 配置来设置一个代理服务器。这个代理服务器会拦截特定的请求,并将其转发到目标后端服务器。
以下是一个基本的proxy配置详解:
// vue.config.js 文件
javascript
// vue.config.js 文件
module.exports = {
// ...
devServer: {
// 配置代理
proxy: {
// 指定需要代理的URL前缀
'/api': {
// 目标API服务器的基础URL(将被替换为实际发送请求的目标地址)
target: 'http://localhost:3000', // 假设后端服务器运行在本地3000端口
// 是否需要改变请求头中的主机信息(true表示模拟同源请求)
changeOrigin: true,
// 路径重写规则,当路径匹配'/api'时,
// 将路径中的'/api'替换成''
pathRewrite: {
'^/api': '' // 如果接口不需要/api前缀,则可以去掉它
},
// 可选配置项:自定义headers
headers: {
'X-Custom-Header': 'foobar'
},
// 可选配置项:重写函数,允许更灵活的路由匹配和替换
onProxyRes(proxyRes, req, res) {
// 对响应进行处理...
},
// 可选配置项:错误处理
onError(err, req, res) {
// 当代理出错时执行
},
// 可选配置项:WebSocket支持
ws: true,
// 其他可选高级配置,如:
// secure: false, // 如果目标是HTTPS,但证书不受信任,设置为false
// logLevel: 'debug', // 设置日志级别
// autoRewrite: true, // 自动重写路径以适应代理目标
// etc.
},
},
},
};
通过上述配置,当Vue应用在开发过程中发出对 /api/xxx 的任何HTTP请求时,这些请求会被自动代理至 http://localhost:3000/xxx ,
从而绕过了浏览器的同源策略限制,使得前端应用能够与不同域名下的后端服务正常交互。
请注意,该配置仅在开发阶段使用,生产环境部署时通常不再需要这种代理,因为生产环境一般可以通过Nginx等反向代理服务器或配置CORS来解决跨域问题
。
示例代码:
// vue.config.js 文件
javascript
const { defineConfig } = require('@vue/cli-service');
const { resolve } = require('path');
const env = process.env;
const IS_PRODUCTION = env.NODE_ENV === 'production';
// 代码压缩工具
const TerserPlugin = require('terser-webpack-plugin');
// 设置版本号
env.VUE_APP_VERSION = require('./package.json').version;
module.exports = defineConfig({
publicPath: './',
assetsDir: 'static',
transpileDependencies: true,
lintOnSave: false,
productionSourceMap: false,
devServer: {
port: 8080,
proxy: {
[env.VUE_APP_API]: {
target: env.VUE_APP_API_PROXY, // 代理的 API 服务器
// secure: false, // https
changeOrigin: true,
pathRewrite: {
[`^${env.VUE_APP_API}`]: '',
},
},
},
client: {
overlay: false,
},
// Webpack 4 devServer.before configurations,In Webpack 5 is devServer.setupMiddlewares configurations
setupMiddlewares: function (middlewares, devServer) {
if (!devServer) {
throw new Error('webpack-dev-server is not defined');
}
return middlewares;
},
},
css: {
// 开启 CSS source maps?
sourceMap: !IS_PRODUCTION,
loaderOptions: {
less: {
lessOptions: {
modifyVars: {},
javascriptEnabled: true,
math: 'always',
},
},
},
},
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
patterns: [resolve(__dirname, 'src/assets/styles/_variable.less'), resolve(__dirname, 'src/assets/styles/global.less')],
},
},
configureWebpack: config => {
// 给输出的js名称添加hash
config.output.filename = "dist/js/[name].[hash].js";
config.output.chunkFilename = "dist/js/[name].[hash].js";
config.optimization = {
minimizer: [
// ============代码压缩 start============
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: false, // Must be set to true if using source-maps in production
extractComments: false, // 删除注释
terserOptions: {
// https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
output: {
comments: false, // 删除注释
},
compress: {
warnings: false, // 若打包错误,则注释这行
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log'],
},
},
}),
// ============代码压缩 end============
],
splitChunks: {
cacheGroups: {
// 将配置文件单独打包
config: {
name: "_config",
test: /[\\/]src[\\/]config[\\/]/,
chunks: "all",
// priority: 3,
reuseExistingChunk: true,
enforce: true
},
}
}
}
},
});