如何将 404 错误重定向到 ExpressJS 中的页面?
Posted
技术标签:
【中文标题】如何将 404 错误重定向到 ExpressJS 中的页面?【英文标题】:How to redirect 404 errors to a page in ExpressJS? 【发布时间】:2011-09-25 14:41:15 【问题描述】:我不知道这样做的功能,有人知道吗?
【问题讨论】:
【参考方案1】:我发现这个例子很有帮助:
https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js
所以,其实就是这部分:
// "app.router" positions our routes
// above the middleware defined below,
// this means that Express will attempt
// to match & call routes _before_ continuing
// on, at which point we assume it's a 404 because
// no route has handled the request.
app.use(app.router);
// Since this is the last non-error-handling
// middleware use()d, we assume 404, as nothing else
// responded.
// $ curl http://localhost:3000/notfound
// $ curl http://localhost:3000/notfound -H "Accept: application/json"
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
app.use(function(req, res, next)
res.status(404);
// respond with html page
if (req.accepts('html'))
res.render('404', url: req.url );
return;
// respond with json
if (req.accepts('json'))
res.json( error: 'Not found' );
return;
// default to plain-text. send()
res.type('txt').send('Not found');
);
【讨论】:
请定义“处理”?究竟是什么将路线标记为已处理? 我认为在那之前没有找到匹配的路线。 仅供参考,现在不推荐使用app.router
。见github.com/strongloop/express/wiki/…
对于 JSON 响应,最好使用 res.json
而不是 res.send()
。它们在您的代码中的行为相同,但使用 res.json
会在将对象自动转换为 .send()
不会的字符串方面发挥作用。安全总比后悔好。 expressjs.com/api.html#res.json
现在这个问题出现在FAQexpressjs.com/starter/faq.html#how-do-you-handle-404s-【参考方案2】:
我认为您应该首先定义所有路线并作为最后一条路线添加
//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res)
res.status(404).send('what???');
);
一个可以运行的示例应用程序:
app.js:
var express = require('express'),
app = express.createServer();
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res)
res.send('hello world');
);
//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res)
res.send('what???', 404);
);
app.listen(3000, '127.0.0.1');
alfred@alfred-laptop:~/node/***/6528876$ mkdir public
alfred@alfred-laptop:~/node/***/6528876$ find .
alfred@alfred-laptop:~/node/***/6528876$ echo "I don't find a function for that... Anyone knows?" > public/README.txt
alfred@alfred-laptop:~/node/***/6528876$ cat public/README.txt
.
./app.js
./public
./public/README.txt
alfred@alfred-laptop:~/node/***/6528876$ curl http://localhost:3000/
hello world
alfred@alfred-laptop:~/node/***/6528876$ curl http://localhost:3000/README.txt
I don't find a function for that... Anyone knows?
【讨论】:
嗯...问题是“*”已经匹配 .js 和 .css 文件,并且它们没有在应用程序中指定...嗯,我不知道是否有一些方法可以捕获与 404 错误完全相同的内容,或者有一种方法可以覆盖“无法获取...”消息。无论如何,谢谢你 您是否使用静态中间件,因为这样您仍然可以提供静态文件?app.get('/public/*', function(req, res) res.sendfile(__dirname + '/public/' + req.url); )
您可以使用此路由发送静态文件。它适用于上述“*”路线。 app.use(express.static(__dirname + '/public'));
对我不起作用,有线。
这对我不起作用,但后来我发现我的 app.use(express.static(...))
在 app.use(app.router)
之后。一旦我切换它们,一切都很好。
+1 用于将@Stephen 的评论添加到您的答案中。这对我也不起作用,直到我把 app.use(app.router) 放在 app.use(express.static(...)) 之后【参考方案3】:
您可以将中间件放在最后一个引发NotFound
错误的位置,
甚至直接渲染404页面:
app.use(function(req,res)
res.status(404).render('404.jade');
);
【讨论】:
下次请考虑更详细的答案...示例通常很好-这是一个很好的示例-但是一些解释也可以非常非常好... +1 非常好!我认为这比最后一条路线要好,因为这样你就不必在最后一次use()
你的app.router
. (就我而言)
此外,这会替换 any 请求的默认行为(不仅是 GET
s)。尝试用另一种方法POST
一个随机URL;它将返回默认的Cannot POST...
。然后攻击者会知道您正在使用 Express.JS。
很好,除了使用ejs你只需要输入res.render('404')
这应该也有 status(404) res.status(404).render('404')【参考方案4】:
上述答案很好,但其中一半您不会得到 404 作为您返回的 HTTP 状态代码,而在另一半中,您将无法获得自定义模板呈现。在 Expressjs 中拥有自定义错误页面(404)的最佳方式是
app.use(function(req, res, next)
res.status(404).render('404_error_template', title: "Sorry, page not found");
);
将此代码放在所有 URL 映射的末尾。
【讨论】:
@SushantGupta - “有效的存在 URL 映射”是什么意思? @JonathanBechtel 在您的非错误 URL 路由之后有上面的代码块。【参考方案5】:在 app.js 的最后一行放这个函数。这将覆盖默认的 page-not-found 错误页面:
app.use(function (req, res)
res.status(404).render('error');
);
它将覆盖所有没有有效处理程序的请求并呈现您自己的错误页面。
【讨论】:
这是您的“app.js 的最后一行”评论有帮助!谢谢! 为我的应用添加了一项功能。谢谢:)【参考方案6】:你的问题的答案是:
app.use(function(req, res)
res.status(404).end('error');
);
还有一篇很棒的文章介绍了为什么这是最好的方法here。
【讨论】:
send
和end
有什么区别?
我觉得他写错了应该是send
我不相信。 send() 设置header,发送数据,最后结束请求,end() 发送数据,不设置header,结束请求。来源:***.com/questions/29555290/…。 Patch92的最后回复【参考方案7】:
express-error-handler 允许您为错误指定自定义模板、静态页面或错误处理程序。它还执行每个应用程序都应该实现的其他有用的错误处理功能,例如防止 4xx 错误 DOS 攻击,以及在不可恢复的错误时正常关闭。以下是你如何做你所要求的:
var errorHandler = require('express-error-handler'),
handler = errorHandler(
static:
'404': 'path/to/static/404.html'
);
// After all your routes...
// Pass a 404 into next(err)
app.use( errorHandler.httpError(404) );
// Handle all unhandled errors:
app.use( handler );
或者对于自定义处理程序:
handler = errorHandler(
handlers:
'404': function err404()
// do some custom thing here...
);
或者对于自定义视图:
handler = errorHandler(
views:
'404': '404.jade'
);
【讨论】:
【参考方案8】:在某些情况下,无法将 404 页面写入最后一个路由来执行,特别是如果您有一个异步路由功能会导致 /route 迟到。在这些情况下可能会采用以下模式。
var express = require("express.io"),
app = express(),
router = express.Router();
router.get("/hello", function (req, res)
res.send("Hello World");
);
// Router is up here.
app.use(router);
app.use(function(req, res)
res.send("Crime Scene 404. Do not repeat");
);
router.get("/late", function (req, res)
res.send("Its OK to come late");
);
app.listen(8080, function ()
console.log("Ready");
);
【讨论】:
太棒了,谢谢!唯一不依赖 express 线性处理的答案(?)(即“将错误处理程序放在最后”)。【参考方案9】:https://github.com/robrighter/node-boilerplate/blob/master/templates/app/server.js
这就是节点样板所做的。
【讨论】:
【参考方案10】:// Add this middleware
// error handler
app.use(function(err, req, res, next)
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : ;
// render the error page
res.status(err.status || 500);
res.render('error');
);
【讨论】:
【参考方案11】:最简单的方法是获取错误页面的全部内容
// Step 1: calling express
const express = require("express");
const app = express();
然后
// require Path to get file locations
const path = require("path");
现在您可以将所有“html”页面(包括错误“html”页面)存储在一个变量中
// Storing file locations in a variable
var indexPg = path.join(__dirname, "./htmlPages/index.html");
var aboutPg = path.join(__dirname, "./htmlPages/about.html");
var contactPg = path.join(__dirname, "./htmlPages/contact.html");
var errorPg = path.join(__dirname, "./htmlPages/404.html"); //this is your error page
现在您只需使用 Get 方法调用页面,并使用 app.get("*") 获取所有无法指向错误页面的路由
//Step 2: Defining Routes
//default page will be your index.html
app.get("/", function(req,res)
res.sendFile(indexPg);
);
//about page
app.get("/about", function(req,res)
res.sendFile(aboutPg);
);
//contact page
app.get("/contact", function(req,res)
res.sendFile(contactPg);
);
//catch all endpoint will be Error Page
app.get("*", function(req,res)
res.sendFile(errorPg);
);
别忘了设置端口并监听服务器:
// Setting port to listen on
const port = process.env.PORT || 8000;
// Listening on port
app.listen(port, function()
console.log(`http://localhost:$port`);
)
现在应该会显示所有无法识别的端点的错误页面!
【讨论】:
【参考方案12】:你好,求解答
const express = require('express');
const app = express();
const port = 8080;
app.get('/', (req, res) => res.send('Hello home!'));
app.get('/about-us', (req, res) => res.send('Hello about us!'));
app.post('/user/set-profile', (req, res) => res.send('Hello profile!'));
//last 404 page
app.get('*', (req, res) => res.send('Page Not found 404'));
app.listen(port, () => console.log(`Example app listening on port $port!`));
【讨论】:
【参考方案13】:覆盖express
中的所有HTTP动词
为了覆盖all HTTP verbs 以及您可以使用的所有剩余路径:
app.all('*', cb)
最终解决方案如下所示:
app.all('*', (req, res) =>
res.status(404).json(
success: false,
data: '404'
)
)
你不应该忘记把路由器放在最后。 因为路由器的顺序很重要。
【讨论】:
【参考方案14】:虽然上面的答案是正确的,但对于那些想要在 IISNODE 中使用它的人,您还需要指定
<configuration>
<system.webServer>
<httpErrors existingResponse="PassThrough"/>
</system.webServer>
<configuration>
在您的 web.config 中(否则 IIS 会吃掉您的输出)。
【讨论】:
谢谢!!!您是互联网上唯一一个似乎知道(或至少分享)的人!欢呼【参考方案15】:可以根据内容类型进行错误处理
另外,根据状态码处理。
app.js
import express from 'express';
// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
// when status is 404, error handler
app.use(function(err, req, res, next)
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : ;
// render the error page
res.status(err.status || 500);
if( 404 === err.status )
res.format(
'text/plain': () =>
res.send(message: 'not found Data');
,
'text/html': () =>
res.render('404.jade');
,
'application/json': () =>
res.send(message: 'not found Data');
,
'default': () =>
res.status(406).send('Not Acceptable');
)
// when status is 500, error handler
if(500 === err.status)
return res.send(message: 'error occur');
);
404.jade
doctype html
html
head
title 404 Not Found
meta(http-equiv="Content-Type" content="text/html; charset=utf-8")
meta(name = "viewport" content="width=device-width, initial-scale=1.0 user-scalable=no")
body
h2 Not Found Page
h2 404 Error Code
如果你可以使用 res.format,你可以编写简单的错误处理代码。
推荐res.format()
而不是res.accepts()
。
如果前面代码出现500错误,则调用if(500 == err.status). . .
【讨论】:
【参考方案16】:上面的代码对我不起作用。
所以我找到了一个真正有效的新解决方案!
app.use(function(req, res, next)
res.status(404).send('Unable to find the requested resource!');
);
或者您甚至可以将其呈现为 404 页面。
app.use(function(req, res, next)
res.status(404).render("404page");
);
希望这对您有所帮助!
【讨论】:
【参考方案17】:如果你使用 express-generator 包:
下一个(错误);
此代码会将您发送到 404 中间件。
【讨论】:
【参考方案18】:发送到自定义页面:
app.get('*', function(req, res)
if (req.accepts('html'))
res.send('404', '<script>location.href = "/the-404-page.html";</script>');
return;
);
【讨论】:
【参考方案19】:我使用下面的处理程序通过静态 .ejs
文件处理 404 错误。
将此代码放入路由脚本中,然后在 app.js
/server.js
/www.js
中要求 file.js
到 app.use()
(如果使用 IntelliJ for NodeJS) p>
您也可以使用静态.html
文件。
//Unknown route handler
router.get("[otherRoute]", function(request, response)
response.status(404);
response.render("error404.[ejs]/[html]");
response.end();
);
这样,正在运行的 express 服务器将使用正确的404 error
进行响应,并且您的网站还可以包含一个正确显示服务器的 404 响应的页面。您还可以在该404 error template
中包含一个navbar
,该404 error template
链接到您网站的其他重要内容。
【讨论】:
【参考方案20】:如果您想从您的函数(路由)重定向到错误页面,请执行以下操作 -
在您的 app.js 中添加一般错误消息代码 -
app.use(function(err, req, res, next)
// set locals, only providing error in development
res.locals.message = err.message
res.locals.error = req.app.get('env') === 'development' ? err :
// render the error page
// you can also serve different error pages
// for example sake, I am just responding with simple error messages
res.status(err.status || 500)
if(err.status === 403)
return res.send('Action forbidden!');
if(err.status === 404)
return res.send('Page not found!');
// when status is 500, error handler
if(err.status === 500)
return res.send('Server error occured!');
res.render('error')
)
在您的函数中,您可以先设置错误状态,然后再使用 next() 让代码流通过上述代码,而不是使用错误页面重定向 -
if(FOUND)
...
else
// redirecting to general error page
// any error code can be used (provided you have handled its error response)
res.status(404)
// calling next() will make the control to go call the step 1. error code
// it will return the error response according to the error code given (provided you have handled its error response)
next()
【讨论】:
【参考方案21】:应该在调用 app.listen.Express 之前设置 404 页面,在路由路径中支持 *。这是一个匹配的特殊字符 任何事物。这可用于创建匹配所有请求的路由处理程序。
app.get('*', (req, res) =>
res.render('404',
title: '404',
name: 'test',
errorMessage: 'Page not found.'
)
)
【讨论】:
【参考方案22】:我在定义所有路由后做的是捕捉潜在的 404 并转发到错误处理程序,如下所示:
const httpError = require('http-errors');
...
// API router
app.use('/api/', routes);
// catch 404 and forward to error handler
app.use((req, res, next) =>
const err = new httpError(404)
return next(err);
);
module.exports = app;
【讨论】:
【参考方案23】:在 Express 中,404 响应不是错误的结果,因此错误处理程序中间件不会捕获它们。您需要做的就是在堆栈的最底部(在所有其他函数下方)添加一个中间件函数来处理 404 响应:
app.use(function (req, res, next)
// YOU CAN CREATE A CUSTOM EJS FILE TO SHOW CUSTOM ERROR MESSAGE
res.status(404).render("404.ejs")
)
【讨论】:
【参考方案24】:首先,创建一个路由js文件。接下来,创建一个 error.ejs 文件(如果您使用的是 ejs)。最后,在你的路由文件中添加如下代码
router.get('*', function(req, res)
res.render('error');
);
【讨论】:
认为这已经很好地涵盖了。既然有更好的答案,为什么还要发布这个?【参考方案25】:app.get('*',function(req,res)
res.redirect('/login');
);
【讨论】:
以上是关于如何将 404 错误重定向到 ExpressJS 中的页面?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5.2 如何将所有 404 错误重定向到主页
如何使用 Codeigniter 在自定义 404 页面中重定向 404 错误?
如果用户在页面名称之后输入尾随“/”(或“/”之后的任何内容),我如何将用户重定向到错误 404 页面?