node.js 将请求转发到备用请求处理程序而不是重定向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18136323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forward request to alternate request handler instead of redirect
提问by user1328174
I'm using Node.js with express and already know the existence of response.redirect().
我正在将 Node.js 与 express 一起使用,并且已经知道response.redirect().
However, I'm looking for more of a forward()functionality similar to java that takes the same parameters as redirect, but internally forwards the request instead of having the client perform the redirect.
但是,我正在寻找更多forward()类似于 java的功能,它采用与重定向相同的参数,但在内部转发请求,而不是让客户端执行重定向。
To clarify, I am not doing a proxy to a different server. I'd like to forward('/other/path')directly within the same app instance
澄清一下,我没有为不同的服务器做代理。我想forward('/other/path')直接在同一个应用程序实例中
It wasn't apparently obvious how to do this from the express documentation. Any help?
从快速文档中如何做到这一点显然并不明显。有什么帮助吗?
回答by Peter Lyons
You just need to invoke the corresponding route handler function.
您只需要调用相应的路由处理函数。
Option 1: route multiple paths to the same handler function
选项 1:将多个路径路由到同一个处理函数
function getDogs(req, res, next) {
//...
}}
app.get('/dogs', getDogs);
app.get('/canines', getDogs);
Option 2: Invoke a separate handler function manually/conditionally
选项 2:手动/有条件地调用单独的处理程序函数
app.get('/canines', function (req, res, next) {
if (something) {
//process one way
} else {
//do a manual "forward"
getDogs(req, res, next);
}
});
Option 3: call next('route')
选项3:打电话 next('route')
If you carefully order your router patterns, you can call next('route'), which may achieve what you want. It basically says to express 'keep moving on down the router pattern list', instead of a call to next(), which says to express 'move down the middleware list (past the router)`.
如果您仔细订购路由器模式,则可以调用next('route'),这可能会实现您想要的。它基本上表示“继续沿路由器模式列表向下移动”,而不是调用next(),它表示“向下移动中间件列表(经过路由器)”。
回答by Tom
You can implement forward(aka rewrite) functionality by changing request urlproperty and calling next('route').
您可以实现前进(又名重写改变请求)的功能url属性和调用next('route')。
Note that the handler performing forward needs to be configured before other routes which you perform forwards to.
请注意,执行转发的处理程序需要在您执行转发的其他路由之前进行配置。
This is example of forwardingall *.htmldocuments to routes without .htmlextension (suffix).
这是将所有*.html文档转发到没有.html扩展名(后缀)的路由的示例。
function forwards(req, res, next) {
if (/(?:.+?)\.html$/.test(req.url)) {
req.url = req.url.replace(/\.html$/, '');
}
next('route');
}
You call next('route')as the last operation. The next('route')passes control to subsequent routes.
您调用next('route')作为最后一个操作。将next('route')控制传递到随后的路由。
As mentioned above, you need to configure forwards handler as one of the first handlers.
如上所述,您需要将转发处理程序配置为第一个处理程序之一。
app.get('*', forwards);
// ...
app.get('/someroute', handler);
The above example will return the same content for /somerouteas well as /someroute.html. You could also provide an object with a set of forward rules ({ '/path1': '/newpath1', '/path2': '/newpath2' }) and use them in forwardmechanism.
上面的例子将返回相同的内容/someroute,以及/someroute.html。您还可以为对象提供一组转发规则 ( { '/path1': '/newpath1', '/path2': '/newpath2' }) 并在转发机制中使用它们。
Note that regular expression used in forwardsfunction is simplified for mechanism presentation purposes. You would need to extend it (or perform check on req.path) if you would like to use querystring parameters etc.
请注意,forwards函数中使用的正则表达式为机制演示目的进行了简化。req.path如果您想使用查询字符串参数等,则需要扩展它(或执行检查)。
I hope that will help.
我希望这会有所帮助。
回答by Loren
For Express 4+
快递 4+
Using the nextfunction does not work if the next handler is not added in the right order. Instead of using next, I use the router to register the handlers and call
next如果未按正确顺序添加下一个处理程序,则无法使用该函数。next我没有使用,而是使用路由器来注册处理程序并调用
app.get("/a/path", function(req, res){
req.url = "/another/path";
app.handle(req, res);
}
Or for HTML5 mode of React/Angular
或者对于 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);
});
回答by Quoc Quach
Using the nextfunction does not work if the next handler is not added in the right order. Instead of using next, I use the router to register the handlers and call
next如果未按正确顺序添加下一个处理程序,则无法使用该函数。next我没有使用,而是使用路由器来注册处理程序并调用
router.get("/a/path", function(req, res){
req.url = "/another/path";
router.handle(req, res);
}
回答by Eugene Song
Express 4+ with nested routers
带有嵌套路由器的 Express 4+
Instead of having to use the outside of route/function app, you can use req.app.handle
不必使用 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");
});
回答by Yubq
app.get('/menzi', function (req, res, next) {
console.log('menzi2');
req.url = '/menzi/html/menzi.html';
// res.redirect('/menzi/html/menzi.html');
next();
});
This is my code:when user enter "/menzi",the server will give the page /menzi/html/menzi.html to user, but the url in the browser will not change;
这是我的代码:当用户输入“/menzi”时,服务器会将页面/menzi/html/menzi.html给用户,但浏览器中的url不会改变;
回答by Aminadav Glickshtein
You can use run-middlewaremodule exactly for that. Just run the handler you want by using the URL & method & data.
您可以run-middleware完全使用模块。只需使用 URL & 方法 & 数据运行您想要的处理程序。
https://www.npmjs.com/package/run-middleware
https://www.npmjs.com/package/run-middleware
For example:
例如:
app.runMiddleware('/get-user/20',function(code,body,headers){
res.status(code).send(body)
})

