【问题标题】:How to redirect 404 errors to a page in ExpressJS?如何将 404 错误重定向到 ExpressJS 中的页面?
【发布时间】:2011-09-25 14:41:15
【问题描述】:

我不知道这样做的功能,有人知道吗?

【问题讨论】:

    标签: node.js express


    【解决方案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');
    });
    

    【讨论】:

    【解决方案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/stackoverflow/6528876$ mkdir public
    alfred@alfred-laptop:~/node/stackoverflow/6528876$ find .
    alfred@alfred-laptop:~/node/stackoverflow/6528876$ echo "I don't find a function for that... Anyone knows?" > public/README.txt
    alfred@alfred-laptop:~/node/stackoverflow/6528876$ cat public/README.txt 
    
    .
    ./app.js
    ./public
    ./public/README.txt
    
    alfred@alfred-laptop:~/node/stackoverflow/6528876$ curl http://localhost:3000/
    hello world
    alfred@alfred-laptop:~/node/stackoverflow/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 请求的默认行为(不仅是 GETs)。尝试用另一种方法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

    【讨论】:

    • sendend有什么区别?
    • 我觉得他写错了应该是send
    • 我不相信。 send() 设置header,发送数据,最后结束请求,end() 发送数据,不设置header,结束请求。来源:stackoverflow.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】:
      【解决方案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.jsapp.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】:

                        如果您想从您的函数(路由)重定向到错误页面,请执行以下操作 -

                        1. 在您的 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')
                          })
                          
                        2. 在您的函数中,您可以先设置错误状态,然后再使用 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');
                                });
                                

                                【讨论】:

                                  猜你喜欢
                                  • 2016-01-06
                                  • 2015-08-01
                                  • 2023-03-27
                                  • 1970-01-01
                                  • 2015-03-25
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多