vue 前端可配置式跨域解决方案
前言
基于pm2 Node应用的进程管理器,具体安装及作用等步骤请自行搜索。
具体需求
- 项目基于vue-cli开发,在执行
yarn build
或者npm run build
后, 只会生成一个dist文件夹,里面是一套静态文件,无法直接跑在pm2上。除非以pm2 start npm -- run dev
的方式去跑。但这样其实是直接运行在npm上的, 没有用打包好的文件。 - 项目在开发过程中与后端之间处于跨域状态,开发过程中,在
vue.config.js
中配置了proxy进行跨域。
解决方案
- 引入
express
解决 pm2 执行的问题,无需修改已开发完成的代码。 - 引入
express-http-proxy
解决跨域访问的问题,无需修改已开发完成的代码。
解决步骤
- 引入
express
和http-proxy-middleware
npm install express
npm install http-proxy-middleware
- 新建根启动文件xxx.js(名字可自定, 可根据不同环境新建不同的文件)
// 自定义配置项
// 想要监听项目的端口号
const port = '8092';
// vue打包后文件夹的相对路径
const staticPath = './dist';
//代理路径
const apiTargetUrl = 'http://localhost:8081';
// 启用 express 应用框架
const express = require('express');
const path = require('path');
const app = express();
// 启用 express-http-proxy 跨域配置
const {createProxyMiddleware} = require('http-proxy-middleware')
app.use('/api', createProxyMiddleware({
target: apiTargetUrl,
changeOrigin: true,
pathRewrite: {
'^/api': ''
},
// ws: true, //当需要websocket的时候开启
logLevel: 'warn' //生产环境下,打印warn级别日志;若出现异常,可打开debug级别。
}));
app.use(express.static(staticPath))
app.listen(port, (err) => {
if (err) {
console.error(err);
} else {
console.log(`=== 项目启动成功,监听端口:${port} ===`);
}
});
- 新建pm2 ecosystem.config.js (可选, 主要为了固定参数)
pm2 ecosystem
文件配置如下, start.js为步骤三的启动文件.
module.exports = {
apps: [{
name: 'projectName',// 项目名称
script: './server-config.js', //启动文件路径
log_date_format: 'YYYY-MM-DD HH:mm:ss' //pm2项目日志打印时,输出的日期格式
}]
};
打包上载服务器
本地:
npm run build
将以下几个文件上传
- dist文件夹
- node_modules文件夹
- 如果觉得node_modules太大,可以把package.json复制到一个空文件夹里面,仅保留express及其他相关依赖。然后执行
npm install
。这样node_modules
文件夹中就只会包含相关依赖文件,让部署更轻松。
- 如果觉得node_modules太大,可以把package.json复制到一个空文件夹里面,仅保留express及其他相关依赖。然后执行
- xxx.js express启动文件
- ecosystem.config.js pm2启动文件(可选)
- package.json (可选, pm2会读取该文件的一些参数)
服务器:( projectName 请替换成自己的项目名 )
pm2 delete projectName;
pm2 start ecosystem.config.js;
pm2 logs projectName --nostream;
解决vue-router 在history模式下 Cannot GET 页面的问题
安装 connect-history-api-fallback (依赖于express)
npm install connect-history-api-fallback
在启动文件中新增两行
const express = require('express');
const path = require('path');
const app = express();
// 新增部分
// 启用 express 单页面History路由模式
const history = require('connect-history-api-fallback');
app.use(history());
...
解决项目在生产环境HTTP安全问题
安装helmet
npm install helmet
在启动文件中新增以下配置
// 启用 express 应用框架
const express = require('express');
const path = require('path');
const app = express();
// 新增部分
// 启用 HTTP 安全
const helmet = require('helmet');
app.use(helmet());
...
启用Gzip压缩
安装compression
npm install compression
在启动文件中新增以下配置
...
//开启Gzip提高加载速度
const compression = require('compression');
app.use(compression());
//删除原先的app.use(express.static(staticPath))
app.use(express.static(path.join(__dirname, staticPath)));
//项目启动
app.listen(port, (err) => {
if (err) {
console.error(err);
} else {
console.log(`=== 项目启动成功,监听端口:${port} ===`);
}
});
完整配置文件
// 自定义配置项
// 想要监听项目的端口号
const port = '8080';
// vue打包后文件夹的相对路径
const staticPath = './dist';
//代理路径
const apiTargetUrl = 'http://localhost:8081';
// 启用 express 应用框架
const express = require('express');
const path = require('path');
const app = express();
// 启用 HTTP 安全
const helmet = require('helmet');
app.use(helmet());
// 启用 express 单页面History路由模式
const history = require('connect-history-api-fallback');
app.use(history());
// 启用 express-http-proxy 跨域配置
const {createProxyMiddleware} = require('http-proxy-middleware')
app.use('/api', createProxyMiddleware({
target: apiTargetUrl,
changeOrigin: true,
pathRewrite: {
'^/api': ''
},
// ws: true, //当需要websocket的时候开启
logLevel: 'warn' //生产环境下,打印warn级别日志;若出现异常,可打开debug级别。
}));
//开启Gzip提高加载速度
const compression = require('compression');
app.use(compression());
app.use(express.static(path.join(__dirname, staticPath)));
//项目启动
app.listen(port, (err) => {
if (err) {
console.error(err);
} else {
console.log(`=== 项目启动成功,监听端口:${port} ===`);
}
});