我正在使用带有express的Node.js并且已经知道response.redirect()
的存在。
但是,我正在寻找更多类似于java的forward()
功能,它采用与重定向相同的参数,但在内部转发请求而不是让客户端执行重定向。
为了澄清,我没有代理其他服务器。我想直接在同一个应用实例
中forward('/other/path')
如何从快递文档中做到这一点并不明显。有什么帮助吗?
答案 0 :(得分:22)
您只需要调用相应的路由处理函数。
function getDogs(req, res, next) {
//...
}}
app.get('/dogs', getDogs);
app.get('/canines', getDogs);
app.get('/canines', function (req, res, next) {
if (something) {
//process one way
} else {
//do a manual "forward"
getDogs(req, res, next);
}
});
next('route')
如果您仔细订购路由器模式,可以拨打next('route')
,这可能会达到您想要的效果。它基本上表示要“继续沿着路由器模式列表继续前进”,而不是调用next()
,这表示“向下移动中间件列表(通过路由器)”。
答案 1 :(得分:18)
您可以通过更改请求url
属性并调用next('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')
将控制权传递给后续路线。
如上所述,您需要将转发处理程序配置为第一个处理程序之一。
app.get('*', forwards);
// ...
app.get('/someroute', handler);
以上示例将返回/someroute
以及/someroute.html
的相同内容。您还可以为对象提供一组转发规则({ '/path1': '/newpath1', '/path2': '/newpath2' }
),并在转发机制中使用它们。
请注意,forwards
函数中使用的正则表达式是为了机制表示而简化的。如果您想使用查询字符串参数等,则需要对其进行扩展(或对req.path
执行检查)。
我希望这会有所帮助。
答案 2 :(得分:9)
如果未按正确顺序添加下一个处理程序,则使用next
函数不起作用。我使用路由器注册处理程序并调用
next
router.get("/a/path", function(req, res){
req.url = "/another/path";
router.handle(req, res);
}
答案 3 :(得分:6)
对于Express 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);
});
答案 4 :(得分: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提供给用户,但浏览器中的网址不会更改;
答案 5 :(得分: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)
})
答案 6 :(得分:0)
具有嵌套路由器的Express 4 +
您不必使用路由/功能的外部功能 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");
});