app.use 和 app.get *在代理中的区别*

Difference between app.use and app.get *in proxying*

我希望能更好地理解 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'));

具体来说,"index" 页面被代理并提供,内容如下:

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

并且客户端请求 javascript 反应包,但随后 "nothing happens"。

我有理由相信当它工作时不涉及 "other" HTTP 请求(除了 GET 和 POST)因为 none 被记录了。

那会有什么区别?

尝试将此日志记录放在顶部,它应该有助于阐明正在发生的事情:

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

When called from a middleware, the mount point is not included in req.path.

调用 app.use 的路径有点像 'starts with',任何匹配的都会被丢弃。对于 * 匹配所有内容,因此它会丢弃所有内容。

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

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

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

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