Express代理Vue应用调用API仅返回{success: true}无数据问题求助
看起来你的问题出在几个关键的中间件配置上,我帮你一步步梳理和修复:
1. 核心问题:自定义CORS中间件直接阻断了请求流程
你在server.js里写了这段中间件:
app.use(function (req, res, next) { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'X-Requested-With') res.status(200).json({ success: true}); // 这里直接发送了响应! next() });
这个中间件挂载在所有路由(包括你的代理路由)之前,任何请求进来都会先返回{success: true}——虽然你调用了next(),但HTTP响应已经发送完毕,后续的代理逻辑根本没有机会执行,这就是你永远只拿到这个结果的原因。
修复方法:
直接删除这段中间件!你已经使用了cors包处理跨域,重复的自定义CORS逻辑不仅多余,还会打断请求流程。
2. 代理中间件写法错误,未生效
你原来的代理创建方式是:
const apiProxy = (req, res) => { createProxyMiddleware(options); } app.use('/checkCustomer', apiProxy);
这里的apiProxy只是调用了createProxyMiddleware,但并没有把它返回的中间件函数应用到请求上,相当于代理根本没起作用。
修复方法:
直接把createProxyMiddleware的返回值作为中间件挂载:
const apiProxy = createProxyMiddleware(options); app.use('/checkCustomer', apiProxy);
或者更简洁的写法:
app.use('/checkCustomer', createProxyMiddleware(options));
3. 静态文件服务配置冗余,易出路径问题
你原来的静态服务写了冗余路由:
app.use(express.static('dist')); app.use('/dist', (req, res) => { res.sendFile(__dirname + 'dist/index.html'); }); app.use('/dist/assets/main.css', (req, res) => { res.sendFile(__dirname + 'dist/assets/main.css'); });
其实express.static('dist')已经会自动处理dist目录下的所有静态资源,不需要单独为路由或文件写规则。另外,路径拼接最好用Node.js的path模块,避免相对路径出错。
修复方法:
先引入path模块:
const path = require('path');
然后替换静态服务配置:
// 托管dist目录下的静态资源 app.use(express.static(path.join(__dirname, 'dist'))); // 处理SPA路由:访问不存在的路由时返回index.html(适配Vue单页应用) app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); });
4. 优化CORS配置(可选)
因为你的前端和Express服务器同域(都是localhost:3000),通过代理转发请求到API,所以不需要复杂的CORS配置。你原来的cors配置里origin: ['https://myAPI.com']逻辑反了,应该是允许前端访问,但因为用了代理,前端请求的是同域的Express,所以可以简化为:
app.use(cors()); // 允许所有来源,也可根据实际需求限制
修复后的完整server.js参考
const express = require('express'); const https = require('https'); const cors = require('cors'); const { createProxyMiddleware } = require('http-proxy-middleware'); const fs = require('fs'); const path = require('path'); const app = express(); // 简化CORS配置 app.use(cors()); // 解析JSON请求体 app.use(express.json()); // 托管静态资源 app.use(express.static(path.join(__dirname, 'dist'))); // 代理配置,新增changeOrigin确保请求头正确 const proxyOptions = { target: 'https://myAPI.com', pathRewrite: { '^/checkCustomer': '' }, changeOrigin: true, }; // 挂载代理中间件 app.use('/checkCustomer', createProxyMiddleware(proxyOptions)); // SPA路由处理 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); }); // 启动HTTPS服务器 https.createServer( { key: fs.readFileSync("thisIsMyServerKey.key"), cert: fs.readFileSync("thisIsMyServerCert.cert"), }, app ).listen(3000, () => { console.log('Listening on: https://localhost:3000'); });
注意新增的changeOrigin: true很重要,它会修改代理请求的Host头为目标API的Host,避免API因Host不匹配拒绝请求。
现在重启服务器测试,点击按钮后应该就能正确拿到API返回的数据了!
备注:内容来源于stack exchange,提问作者Takuhii

