【问题标题】:How to proxy to many different targets using http-proxy-middleware?如何使用 http-proxy-middleware 代理到许多不同的目标?
【发布时间】:2019-06-13 00:38:41
【问题描述】:

http-proxy-middleware 库中,文档声明您可以使用target 选项指定您希望代理请求的位置。但是,它们还允许您使用 router 选项来指定将用于在运行时功能解析目标的函数。

文档:https://www.npmjs.com/package/http-proxy-middleware

我正在使用 TypeScript,如果我查看代理的声明文件,我可以看到:

您可以在此处看到routertarget 都可以为空。我的假设是,如果你使用一个,另一个可以省略,但你总是需要至少 1 个。

但是,如果我像这样使用router 属性:

app.use("/pipe", proxy({
    changeOrigin: true,
    router: (req: IIncomingMessageWithCookies) => {
        return "https://www.google.com";
    }
}));

并省略target,然后在运行时出现此错误:

> node ./dist/app.js

C:\SkyKick\SkyKick.SEWR\src\node_modules\http-proxy-middleware\lib\config-factory.js:43
    throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING)
    ^

Error: [HPM] Missing "target" option. Example: {target: "http://www.example.org"}
    at Object.createConfig (C:\SkyKick\SkyKick.SEWR\src\node_modules\http-proxy-middleware\lib\config-factory.js:43:11)
    at new HttpProxyMiddleware (C:\SkyKick\SkyKick.SEWR\src\node_modules\http-proxy-middleware\lib\index.js:17:30)
    at module.exports (C:\SkyKick\SkyKick.SEWR\src\node_modules\http-proxy-middleware\index.js:4:10)
    at Object.<anonymous> (C:\SkyKick\SkyKick.SEWR\src\dist\app.js:8:18)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)

我意识到我可以将几乎任何东西放入target,它会运行得很好,而我的router 函数是实际定义目标代理的东西。这只是库的错误还是我误解了这两个选项的用途?

【问题讨论】:

    标签: node.js typescript proxy http-proxy http-proxy-middleware


    【解决方案1】:

    同时包含targetrouter 属性。 router 属性用于针对特定请求重新定位 option.target

    import express = require('express');
    import proxy = require('http-proxy-middleware');
    
    const app = express();
    
    app.use('/api', proxy({
        target: 'http://www.github.com',
        changeOrigin: true,
        router: function (req: IncomingMessage) {
            return 'http://www.stackoverflow.com'
        }
    }));
    
    app.listen(3000);
    

    target 属性在Config 类型中是可选的,因为当我们use the shorthand like this 时它允许为空:

    app.use('/api', proxy('http://www.github.com',
        {
            changeOrigin: true,
            router: function (req: IncomingMessage) {
                return 'http://www.stackoverflow.com'
            }
        }
    ));
    

    【讨论】:

    • 好吧,关于可空属性,这完全有道理,但是我仍然认为我不明白强迫开发人员像这样重新定位目标意味着什么,而不仅仅是有许多不同的方法来定义一个单一财产。在我的场景中,我想采用一些任意格式的域和 URL 架构并将这些来源映射到许多不同的目标。在那种情况下,我没有任何 1 个目标可以使用,不是吗?
    • 我查看了源代码,确实看到 router 基本上只是像我想象的那样覆盖了原始的 options.target 属性,但是仍然需要在其中添加 target 感觉很奇怪这个案例。我觉得无论实现如何,验证逻辑都应该检查是否存在至少一个。
    • 关于您想要做的映射,您是否考虑过将router 值设置为对象而不是函数?
    • target 为空且router 有值时,我可以理解您关于引发错误的意思。乍一看,原始开发人员似乎很懒惰。不过,我很感激,可能有一些更深层次的原因会在进一步调查中显现出来。而且,如果没有更深层次的原因,将 target 设置为 http://required-target.why 之类的东西是一种合理且廉价的解决方法。
    • 我不认为我可以将它设置为一个对象,因为这意味着会发生一组有限的映射,而实际上我需要映射完全传统并扩展到任何数字都基于传入请求 URI 的架构。话虽如此,简单地将一些“垃圾”放入target 属性似乎工作得很好。我只是想确认我理解它是如何工作的。这似乎是牵强附会的图书馆本身看到它是如何被广泛采用的问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多