42

我正在使用带有 express 的 Node.js,并且已经知道response.redirect().

但是,我正在寻找更多forward()类似于 java 的功能,它采用与重定向相同的参数,但在内部转发请求而不是让客户端执行重定向。

澄清一下,我没有做代理到不同的服务器。我想forward('/other/path')直接在同一个应用程序实例中

从 express 文档中如何做到这一点显然并不明显。有什么帮助吗?

4

7 回答 7

26

您只需要调用相应的路由处理函数即可。

选项 1:将多个路径路由到同一个处理函数

function getDogs(req, res, next) {
  //...
}}
app.get('/dogs', getDogs);
app.get('/canines', getDogs);

选项 2:手动/有条件地调用单独的处理函数

app.get('/canines', function (req, res, next) {
   if (something) {
      //process one way
   } else {
      //do a manual "forward"
      getDogs(req, res, next);
   }
});

选项3:调用next('route')

如果您仔细订购路由器模式,您可以调用next('route'),这可能会达到您想要的效果。它基本上说表达“继续向下移动路由器模式列表”,而不是调用next()表示“向下移动中间件列表(经过路由器)”。

于 2013-08-08T21:35:53.680 回答
21

您可以通过更改请求属性和调用来实现转发(又名重写)功能。urlnext('route')

请注意,执行转发的处理程序需要在您执行转发的其他路由之前配置。

这是将所有文档转发到不带扩展名(后缀)的路由的示例。 *.html.html

function forwards(req, res, next) {
    if (/(?:.+?)\.html$/.test(req.url)) {
        req.url = req.url.replace(/\.html$/, '');
    }
    next('route');
}

您调用next('route')作为最后一个操作。将next('route')控制权传递给后续路线。

如上所述,您需要将 forwards 处理程序配置为第一个处理程序之一。

app.get('*', forwards);
// ...
app.get('/someroute', handler);

上面的示例将返回与 和 相同的/someroute内容/someroute.html。您还可以为对象提供一组转发规则 ( { '/path1': '/newpath1', '/path2': '/newpath2' }) 并在转发机制中使用它们。

请注意,forwards函数中使用的正则表达式为机制表示目的而进行了简化。req.path如果您想使用查询字符串参数等,则需要扩展它(或执行检查)。

我希望这会有所帮助。

于 2014-02-27T21:42:23.927 回答
13

对于快递 4+

next如果未按正确顺序添加下一个处理程序,则无法使用该函数。我没有使用,而是next使用路由器来注册处理程序并调用

app.get("/a/path", function(req, res){
    req.url = "/another/path";
    app.handle(req, res);
}

或者对于 React/Angular 的 HTML5 模式

const dir = process.env.DIR || './build';

// Configure http server
let app = express();
app.use('/', express.static(dir));

// This route sends a 404 when looking for a missing file (ie a URL with a dot in it)
app.all('/*\.*', function (req, res) {
    res.status(404).send('404 Not found');
});

// This route deals enables HTML5Mode by forwarding "missing" links to the index.html
app.all('/**', function (req, res) {
    req.url = 'index.html';
    app.handle(req, res);
});
于 2018-02-14T15:07:09.843 回答
11

next如果未按正确顺序添加下一个处理程序,则无法使用该函数。我没有使用,而是next使用路由器来注册处理程序并调用

router.get("/a/path", function(req, res){
    req.url = "/another/path";
    router.handle(req, res);
}
于 2016-02-20T02:52:24.627 回答
2
app.get('/menzi', function (req, res, next) {
        console.log('menzi2');
        req.url = '/menzi/html/menzi.html';
        // res.redirect('/menzi/html/menzi.html');
        next();
});

这是我的代码:当用户输入“/menzi”时,服务器会给用户页面/menzi/html/menzi.html,但浏览器中的url不会改变;

于 2014-11-06T07:04:13.897 回答
2

带有嵌套路由器的 Express 4+

不必使用 route/function 的外部app,您可以使用req.app.handle

"use strict";

const express = require("express");
const app = express();

//
//  Nested Router 1
//
const routerOne = express.Router();

//  /one/base
routerOne.get("/base", function (req, res, next) {
  res.send("/one/base");
});

//  This routes to same router (uses same req.baseUrl)
//  /one/redirect-within-router -> /one/base
routerOne.get("/redirect-within-router", function (req, res, next) {
  req.url = "/base";
  next();
});

//  This routes to same router (uses same req.baseUrl)
//  /one/redirect-not-found -> /one/two/base (404: Not Found)
routerOne.get("/redirect-not-found", function (req, res, next) {
  req.url = "/two/base";
  next();
});

//  Using the full URL
//  /one/redirect-within-app -> /two/base
routerOne.get("/redirect-within-app", function (req, res, next) {
  req.url = "/two/base";

  // same as req.url = "/one/base";
  //req.url = req.baseUrl + "/base";

  req.app.handle(req, res);
});

//  Using the full URL
//  /one/redirect-app-base -> /base
routerOne.get("/redirect-app-base", function (req, res, next) {
  req.url = "/base";
  req.app.handle(req, res);
});



//
//  Nested Router 2
//
const routerTwo = express.Router();

//  /two/base
routerTwo.get("/base", function (req, res, next) {
  res.send("/two/base");
});

//  /base
app.get("/base", function (req, res, next) {
  res.send("/base");
});


//
//  Mount Routers
//
app.use("/one/", routerOne);
app.use("/two/", routerTwo);


//  404: Not found
app.all("*", function (req, res, next) {
  res.status(404).send("404: Not Found");
});
于 2019-04-07T06:58:48.997 回答
1

您可以run-middleware完全使用模块。只需使用 URL & 方法 & 数据运行您想要的处理程序。

https://www.npmjs.com/package/run-middleware

例如:

app.runMiddleware('/get-user/20',function(code,body,headers){
    res.status(code).send(body)
})
于 2016-09-15T09:21:55.087 回答