首先,浏览器报跨域,并不是服务器没有返回,而是,服务器返回了,但是被浏览器拦截了。
其次,http-proxy-middleware解决跨域的方案,本地起了一个node代理服务器(var httpProxy = require('http-proxy')
),通过代理服务器去请求目标服务器,然后返回请求结果。由于浏览器请求的是本地路径,所以不会有跨域问题。
代理服务器http-proxy
也就是node-http-proxy
是一个HTTP可编程的,支持 websockets的代理库。它适合于实现诸如反向代理和负载均衡之类的组件。
var httpProxy = require('http-proxy')
//创建代理服务器
var proxy = httpProxy.createProxyServer({})
var proxyEvents = [
'error',
'proxyReq',
'proxyReqWs',
'proxyRes',
'open',
'close'
]
// 注册代理服务器事件
proxyEvents.forEach(eventName => {
proxy.on(eventName, handlers[eventName])
})
http-proxy-middleware配置
如下示例,解决了cookie跨域问题:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>proxy 跨域</title>
</head>
<body>
<script>
var xhr = new XMLHttpRequest();
// 前端开关:浏览器是否读写 cookie
xhr.withCredentials = true;
// 访问 http-proxy-middleware 代理服务器
xhr.open('get', 'http://localhost:3000/login?user=admin', true);
xhr.send();
</script>
</body>
</html>
中间代理服务使用了http-proxy-middleware中间件,
// 中间代理服务器
const express = require("express");
let proxy = require("http-proxy-middleware");
let app = express();
app.use(
"/",
proxy({
// 代理跨域目标接口
target: "http://www.proxy2.com:8080",
changeOrigin: true,
// 修改响应头信息,实现跨域并允许带 cookie
onProxyRes: function(proxyRes, req, res) {
res.header("Access-Control-Allow-Origin", "http://localhost");
res.header("Access-Control-Allow-Credentials", "true");
},
// 修改响应信息中的 cookie 域名
cookieDomainRewrite: "localhost" // 可以为 false,表示不修改
})
);
app.listen(3000);
// 服务器
const http = require("http");
const qs = require("querystring");
const server = http.createServer();
server.on("request", function(req, res) {
let params = qs.parse(req.url.substring(2));
// 向前台写 cookie
res.writeHead(200, {
"Set-Cookie": "l=a123456;Path=/;Domain=www.proxy2.com;HttpOnly" // HttpOnly:脚本无法读取
});
res.write(JSON.stringify(params));
res.end();
});
server.listen("8080");