【问题标题】:Difference between app.use and app.get *in proxying*app.use 和 app.get *在代理中的区别*
【发布时间】:2017-10-30 03:52:04
【问题描述】:

我希望能更好地理解 express 的 app.get()app.use() 之间的区别。

我了解 app.use 适用于所有 HTTP 动词。

我也读过“app.use() adds middleware rather than a route

我想了解为什么这个事实会导致这种行为......

我有一个 Express API 服务器,它需要代理一个 React 开发 Web 服务器。

这意味着所有不是 API 路由的路由都必须被代理。

当我像这样代理路由时,它可以工作:

var proxy = require('express-http-proxy');

module.exports = function set_react_catchall_routes(app) { 
    /* Final route to send anything else to react server. */
    app.get('*', proxy('localhost:3000'));
    app.post('*', proxy('localhost:3000'));
}

但是当我这样做时它不起作用:

    app.use('*', proxy('localhost:3000'));

具体来说,“索引”页面被代理并提供,内容如下:

 <body>
    <div id="root"></div>
    <script type="text/javascript" src="/static/js/bundle.js"></script>
 </body>

并且客户端请求 javascript react 包,但随后“什么也没发生”。

我有理由确定当它工作时没有涉及“其他”HTTP 请求(GET 和 POST 除外),因为没有记录。

那么有什么区别呢?

【问题讨论】:

    标签: reactjs express http-proxy


    【解决方案1】:

    尝试将此日志放在顶部,它应该有助于澄清发生了什么:

    app.use(function(req, res, next) {
        // req.path will be '/static/js/bundle.js'
        console.log('path1: ' + req.path);
    
        next();
    });
    
    app.use('*', function(req, res, next) {
        // req.path will be '/'
        console.log('path2: ' + req.path);
    
        next();
    });
    
    app.all('*', function(req, res, next) {
        // req.path will be '/static/js/bundle.js'
        console.log('path3: ' + req.path);
    
        next();
    });
    

    当您使用app.use 时,它将删除req.path 的匹配部分。如果您不指定路径(记录第 1 节),它不会删除任何内容。同样,第 3 节使用app.allapp.get 等都以相同的方式工作),这也不会改变req.path。第 2 节才是关键。

    要了解为什么会发生这种情况,请考虑以下示例:

    var router = express.Router();
    
    router.get('/profile', ...);
    
    app.use('/user', router);
    

    当对/user/profile 的请求进入时,app.use 将剥离路径的/user 部分。就router 而言,路径就是/profile

    引用文档,http://expressjs.com/en/4x/api.html#req.path

    从中间件调用时,挂载点不包含在 req.path 中。

    调用app.use 的路径有点像“开始于”,任何匹配的东西都会被丢弃。对于匹配所有内容的*,它会丢弃所有内容。

    如果您快速深入了解express-http-proxy 的源代码,您会发现它使用req.path 来确定代理请求的路径。如果您只使用 app.use 而不使用路径,它应该可以正常工作。

    还有一些与理解app.use类似的其他请求属性:

    • req.urlreq.path 类似,但包含查询字符串。就像req.path 一样,它将与mountpath 匹配的部分被app.use 删除。请注意,Express Request 继承了 Node 的 http.IncomingMessageurl 属性,因此它没有在 Express 文档中明确列出。
    • req.originalUrl 开头与 req.url 相同,但不会被 app.use 更改。
    • req.baseUrl 用于存储路径中被app.use 删除的部分。

    有关所有这三个属性的更多详细信息,请参阅the documentation req.originalUrl

    【讨论】:

    • 远远的,很棒的答案,正是我需要知道的,解释清楚!
    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2015-04-03
    • 2012-12-17
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多