好像终于懂了http-proxy-middleware为何能解决跨域问题

7,276 阅读1分钟

首先,浏览器报跨域,并不是服务器没有返回,而是,服务器返回了,但是被浏览器拦截了。

其次,http-proxy-middleware解决跨域的方案,本地起了一个node代理服务器(var httpProxy = require('http-proxy')),通过代理服务器去请求目标服务器,然后返回请求结果。由于浏览器请求的是本地路径,所以不会有跨域问题。

截屏2021-08-07 下午7.31.11.png

代理服务器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");

参考文章:

让你彻底解决跨域问题