自己试了好久,终于把node.js的代理问题弄清了个大概。首先我本地项目在跨域方面会先请求一个options,成功后才会请求post,于是我一开始在代理中用的代码:
const express = require('express');
const app = express();
app.use('/print/*', proxy({
target: 'http://localhost:8099',
changeOrigin: true,
// 修改响应头信息,实现跨域并允许带cookie
onProxyRes: function (proxyRes, req, res) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');
},
// 修改响应信息中的cookie域名
cookieDomainRewrite: false // 可以为false,表示不修改
}));
问题有两处,1.我的请求链接为http://localhost:9001/print,它根本就不会进这个路由,因为/*是多余的。2.解决问题一后,只有options会进入,post并不会进入
响应头里缺少了个重要的:res.header('Access-Control-Allow-Headers', 'Content-Type');
然后我又加了个:
app.post('/print', (req, res) => {
const target = 'http://localhost:8099/print';
console.log(target, req.body);
axios.post(target, req.body).then((response) => {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials', 'true');
res.json(response.data);
}).catch((err) => {
console.log('poi err' + err.message);
});
});
果然代码不会进入这个post,毕竟前面存在一个use。于是我把use那段注释了,但因为options请求不通所以也不会进入post的路由里。之后我的关注点转移到了组件上,把组件中的请求改成了:
axios.post(url + '/print', params, {
headers: { 'Content-Type': 'multipart/form-data' },
});
这时候居然后端接收到了post请求了,但问题在于参数怎么传都是空……这时试了各种application/json、JSON.stringify()、new FormData()都失效之后又把headers删了。
之后突发奇想,把代理第一段中的use改成了opstions,然后居然正常得通过app.opstions和app.post,而且参数也被后端正常接收到了。
最后又测试了一些东西,发现即使不要app.opstions,把app.post改成app.use,也是行得通的,但那样后端会返回两次数据(第一次的数据因为是options没有参数,所以是有问题),感觉并不是很正规,还是回到原代码好了:
app.options('/print', proxy({
target: 'http://localhost:8099/',
changeOrigin: true,
onProxyRes: function (proxyReq, req, res) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
},
cookieDomainRewrite: false
}));
app.post('/print', (req, res) => {
const target = 'http://localhost:8099/print';
axios.post(target, req.body).then((response) => {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.json(response.data);
}).catch((err) => {
console.log('poi err' + err.message);
});
});