• 如何使用 express 配合代理转发请求


    如何使用 express 配合代理转发请求

    实现一个 express 接口

    const express = require("express");
    const app = express();
    app.use("/abc/11", (req, res) => {
      res.json(11);
    });
    app.listen(9007);
    

    现在我们来通过类似 postman 的工具测试一下这个接口:

    > http -b :9007/abc/11
    11
    

    可以看到服务器正常返回了 11 这个响应内容。

    实现一个反向代理.

    题外话:什么是正向代理反向代理?
    解:直接连代理服务就是正向代理,否则就是反向代理。
    ps: 这可能是最精简的解释了。

    const express = require("express");
    const proxy = require("http-proxy-middleware").createProxyMiddleware;
    const app = express();
    app.use("/", proxy(`http://www.httpbin.org`));
    app.listen(9007);
    

    再来请求一下,看到其实是连接了一个我们根本就没有写的接口。它是 http://www.httpbin.org/ip 返回的内容。

    > http -b :9007/ip
    {
        "origin": "88.76.56.14"
    }
    

    如何实现某些不代理

    假设我需要也能代理,也需要 http://127.0.0.1:9007/abc/11 能返回自己的内容。

    const express = require("express");
    const proxy = require("http-proxy-middleware").createProxyMiddleware;
    const app = express();
    app.use("/", proxy(`http://www.httpbin.org`));
    app.use("/abc/11", (req, res) => {
      res.json(11);
    });
    app.listen(9007);
    
    > http -b :9007/abc/11
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <title>404 Not Found</title>
    <h1>Not Found</h1>
    <p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>
    */
    

    请求 /abc/11 得到了一个 404 Not Found 这是为什么?
    这说明请求并没有走我们自己写的接口,还是被转发了。但转发的目标服务器上并没有这个接口,所以报 404 了。

    为了更清晰一点的表示,我们重新写段代码:

    const express = require("express");
    const proxy = require("http-proxy-middleware").createProxyMiddleware;
    const app = express();
    app.use("/", proxy(`/abc`, { target: `http://www.httpbin.org/anything/` }));
    app.use("/abc/11", (req, res) => {
      res.json(11);
    });
    app.listen(9007);
    
    > http -b :9007/abc
    {
        "origin": "88.76.56.14",
    }
    
    > http -b :9007/abc/11
    {
        "origin": "88.76.56.14",
    }
    */
    

    可以看到,其实都去了 /anything/

    不妨翻阅官网文档看看

    • wildcard path matching

      For fine-grained control you can use wildcard matching. Glob pattern matching is done by micromatch. Visit micromatch or glob for more globbing examples.

      • createProxyMiddleware('**', {...}) matches any path, all requests will be proxied.
      • createProxyMiddleware('**/*.html', {...}) matches any path which ends with .html
      • createProxyMiddleware('/*.html', {...}) matches paths directly under path-absolute
      • createProxyMiddleware('/api/**/*.html', {...}) matches requests ending with .html in the path of /api
      • createProxyMiddleware(['/api/**', '/ajax/**'], {...}) combine multiple patterns
      • createProxyMiddleware(['/api/**', '!**/bad.json'], {...}) exclusion

    可以发现使用 ! 前缀进行排除,并且路径支持数组形式。

    尝试一下:

    const express = require("express");
    const proxy = require("http-proxy-middleware").createProxyMiddleware;
    const app = express();
    app.use(
      "/",
      proxy([`/abc`, `!/abc/11`], { target: `http://www.httpbin.org/anything/` })
    );
    app.use("/abc/11", (req, res) => {
      res.json(11);
    });
    app.listen(9007);
    

    果然,试试就差点逝世。

    [HPM] Proxy created: /abc,!/abc/11  -> http://www.httpbin.org/anything/
    (node:13660) UnhandledPromiseRejectionWarning: Error: [HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]
    

    着重看了一下它的错误,发现第一个 /api 和第二个 /api/** 有些特别。

    然后我也不知道是啥意思。

    那就继续试试:

    const express = require("express");
    const proxy = require("http-proxy-middleware").createProxyMiddleware;
    const app = express();
    app.use(
      "/",
      proxy([`/abc/**`, `!/abc/11`], { target: `http://www.httpbin.org/anything/` })
    );
    app.use("/abc/11", (req, res) => {
      res.json(11);
    });
    app.listen(9007);
    
    > http -b :9007/abc
    {
        "origin": "88.76.56.14",
    }
    
    
    > http -b :9007/abc/11
    11
    
    
    > http -b :9007/abc/12
    {
        "origin": "88.76.56.14",
    }
    

    嗯看起来现在没毛病了,除了 /abc/11 返回了我们自己的内容,其他都是服务器返回的内容。

    留一个习题

    上面的代码我们设置了 pathRewrite 参数为 host,以及另一个 pathRewrite 参数。

    const express = require('express')
    const proxy = require('http-proxy-middleware').createProxyMiddleware
    const app = express()
    app.use('/', proxy(
      [`/abc/**`, `!/abc/11`],
      {
        target: "http://www.httpbin.org",
        pathRewrite: {
          "^/abc": "http://www.httpbin.org/anything/",
        },
      },
    ));
    app.use('/abc/11', (req, res) => {
      res.json(11)
    });
    app.listen(9007);
    

    发送以下请求,结果是什么样的呢?

    > http -b :9007/abc   
    ???
    
    > http -b :9007/abc/11 
    ???
    
    > http -b :9007/abc/12
    ???
    

    参考答案:

    > http -b :9007/abc   
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <title>404 Not Found</title>
    <h1>Not Found</h1>
    <p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>
    
    
    > http -b :9007/abc/11 
    11
    
    > http -b :9007/abc/12
    {
        "origin": "88.76.56.14",
    }
    

    提示:
    有没有想起 webpack devServer 中的 proxy?

  • 相关阅读:
    小程序 视频
    b161: NOIP2007 4.Hanoi双塔问题
    命名规则、.gitignore、freopen()
    c++学习记录(九)
    c++学习笔记(八)
    2020面向对象程序设计寒假作业2
    c++学习记录(七)
    c++学习记录(六)
    c+学习记录(五)
    c++学习记录(四)
  • 原文地址:https://www.cnblogs.com/daysme/p/15677422.html
Copyright © 2020-2023  润新知