Wie leite ich 404-Fehler auf eine Seite in ExpressJS um?

203

Ich kenne keine Funktion dafür, kennt jemand eine?

Hexacyanid
quelle

Antworten:

274

Ich fand dieses Beispiel sehr hilfreich:

https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js

Also ist es eigentlich dieser Teil:

// "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.send({ error: 'Not found' });
    return;
  }

  // default to plain-text. send()
  res.type('txt').send('Not found');
});
Felix
quelle
Bitte definieren Sie "behandelt"? Was genau kennzeichnet die Route als bearbeitet?
Timo Huovinen
1
Ich nahm an, dass bis zu diesem Zeitpunkt keine passende Route gefunden wurde.
Felix
2
Zu Ihrer Information, die Verwendung von app.routerist jetzt veraltet. Siehe github.com/strongloop/express/wiki/…
iX3
2
Für die JSON-Antwort ist es möglicherweise besser, res.jsonanstelle von zu verwenden res.send(). Sie würden sich in Ihrem Code genauso verhalten, aber die Verwendung von res.jsonwird bei der automatischen Konvertierung von Objekten in Zeichenfolgen, bei denen dies .send()nicht der Fall ist, etwas Magie bewirken . Sicher ist sicher. expressjs.com/api.html#res.json
wgp
9
Jetzt erscheint diese Frage in den FAQ expressjs.com/starter/faq.html#how-do-you-handle-404s-
Ivan Fraixedes
157

Ich denke, Sie sollten zuerst alle Ihre Routen definieren und als letzte Route hinzufügen

//The 404 Route (ALWAYS Keep this as the last route)
app.get('*', function(req, res){
  res.status(404).send('what???');
});

Eine Beispiel-App, die funktioniert:

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?
Alfred
quelle
6
Nun ... das Problem ist, dass das "*" bereits mit den .js- und .css-Dateien übereinstimmt und sie nicht in der App angegeben sind ... nun, ich weiß nicht, ob es eine Möglichkeit gibt, genau die zu fangen Das Gleiche wie der 404-Fehler oder eine Möglichkeit, die Meldung "Kann nicht erhalten ..." zu überschreiben. Wie auch immer, danke
1
Verwenden Sie statische Middleware, weil Sie dann noch statische Dateien bereitstellen können?
Alfred
4
app.get('/public/*', function(req, res){ res.sendfile(__dirname + '/public/' + req.url); })Auf dieser Route können Sie statische Dateien senden. es funktioniert gut mit der obigen "*" Route. app.use(express.static(__dirname + '/public'));funktioniert bei mir nicht, verkabelt.
Chris
25
Dies funktionierte nicht für mich, aber dann entdeckte ich , dass mein app.use(express.static(...))kam nach app.use(app.router). Sobald ich sie gewechselt hatte, kam alles gut heraus.
Stephen
5
+1 für das Hinzufügen von @ Stephens Kommentar zu Ihrer Antwort. Dies funktionierte auch nicht für mich, bis ich app.use (app.router) NACH app.use (express.static (...))
braitsch
37

Sie können eine Middleware an der letzten Position platzieren, die einen NotFoundFehler
auslöst , oder die 404-Seite sogar direkt rendern:

app.use(function(req,res){
    res.status(404).render('404.jade');
});
Ganesh Kumar
quelle
9
Bitte überlegen Sie sich beim nächsten Mal eine etwas ausführlichere Antwort ... Beispiele sind normalerweise in Ordnung - und dies ist ein gutes Beispiel - aber einige Erklärungen können auch sehr, sehr gut sein ...
Tonny Madsen
2
+1 Sehr gut! Ich denke, das ist besser als eine letzte Route, denn so musst du nicht zum letzten Mal use()deine app.router. (wie in meinem Fall)
Alba Mendez
Außerdem ersetzt dies das Standardverhalten bei jeder Anforderung (nicht nur bei GETs). Versuchen Sie es POSTmit der anderen Methode mit einer zufälligen URL. Es wird die Standardeinstellung zurückgegeben Cannot POST.... Ein Angreifer würde dann wissen, dass Sie Express.JS verwenden.
Alba Mendez
Sehr gut, außer mit ejs muss man nur setzenres.render('404')
locrizak
Dies sollte wahrscheinlich auch den Status (404) res.status (404) .render ('404') haben
MartinWebb
32

Die obigen Antworten sind gut, aber in der Hälfte davon erhalten Sie nicht 404, wenn Ihr HTTP-Statuscode zurückgegeben wird, und in der anderen Hälfte können Sie keine benutzerdefinierte Vorlage rendern lassen. Der beste Weg, um eine benutzerdefinierte Fehlerseite (404) in Expressjs zu haben, ist

app.use(function(req, res, next){
    res.status(404).render('404_error_template', {title: "Sorry, page not found"});
});

Platzieren Sie diesen Code am Ende aller Ihrer URL-Zuordnungen.

Sushant Gupta
quelle
@SushantGupta - Was meinst du mit "gültigen existenziellen URL-Zuordnungen"?
Jonathan Bechtel
@JonathanBechtel Wie in haben Sie den obigen Codeblock nach Ihren nicht fehlerhaften URL-Routen.
Sushant Gupta
6

In der letzten Zeile von app.js setzen Sie einfach diese Funktion. Dadurch wird die Standardfehlerseite "Seite nicht gefunden" überschrieben:

app.use(function (req, res) {
    res.status(404).render('error');
});

Es überschreibt alle Anforderungen, die keinen gültigen Handler haben, und rendert Ihre eigene Fehlerseite.

Vivek Bajpai
quelle
2
Es war Ihr "letzte Zeile von app.js" Kommentar, der geholfen hat! Vielen Dank!
C0NFUS3D
Meiner App wurde eine Funktion hinzugefügt. Danke :)
Pramesh Bajracharya
5

Die Antwort auf Ihre Frage lautet:

app.use(function(req, res) {
    res.status(404).end('error');
});

Und es gibt einen großartigen Artikel darüber, warum es hier der beste Weg ist .

Marius Cotofana
quelle
1
Was ist der Unterschied zwischen sendund end?
Timo Huovinen
Ich denke, er hat falsch geschrieben, es sollte seinsend
Zaid abu khalaf
4

Mit dem Express-Fehler-Handler können Sie benutzerdefinierte Vorlagen, statische Seiten oder Fehler-Handler für Ihre Fehler angeben. Es werden auch andere nützliche Fehlerbehandlungsfunktionen ausgeführt, die jede App implementieren sollte, z. B. der Schutz vor 4xx-Fehler-DOS-Angriffen und das ordnungsgemäße Herunterfahren bei nicht behebbaren Fehlern. So machen Sie das, wonach Sie fragen:

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 );

Oder für einen benutzerdefinierten Handler:

handler = errorHandler({
  handlers: {
    '404': function err404() {
      // do some custom thing here...
    }
  }
}); 

Oder für eine benutzerdefinierte Ansicht:

handler = errorHandler({
  views: {
    '404': '404.jade'
  }
});
Eric Elliott
quelle
4

In einigen Fällen kann die 404-Seite nicht so geschrieben werden, dass sie als letzte Route ausgeführt wird, insbesondere wenn Sie über eine asynchrone Routing-Funktion verfügen, die eine / route zu spät zur Party bringt. Das folgende Muster könnte in diesen Fällen übernommen werden.

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");
});
Dennis Mathew Philip
quelle
2
Genial, danke! Die einzige Antwort (?), Die nicht auf der linearen Verarbeitung von Express beruht (dh "Setzen Sie einfach den Fehlerbehandler an das Ende").
Nick Grealy
2
// 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');
  });
ASHISH RANJAN
quelle
2

Der einfachste Weg, dies zu tun, besteht darin, einen Fang für die Fehlerseite zu haben

// Step 1: calling express
const express = require("express");
const app = express();

Dann

// require Path to get file locations
const path = require("path");

Jetzt können Sie alle Ihre "HTML" -Seiten (einschließlich einer fehlerhaften "HTML" -Seite) in einer Variablen speichern

// 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

Jetzt rufen Sie einfach die Seiten mit der Get-Methode auf und haben einen Haken für alle Routen, die nicht verfügbar sind, um mit app.get ("*") auf Ihre Fehlerseite zu gelangen.

//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);
});

Vergessen Sie nicht, einen Port einzurichten und auf den Server zu warten:

// Setting port to listen on
const port = process.env.PORT || 8000;
// Listening on port
app.listen(port, function(){
  console.log(`http://localhost:${port}`);
})

Dies sollte nun Ihre Fehlerseite für alle nicht erkannten Endpunkte anzeigen!

Kean Amaral
quelle
1

Während die obigen Antworten korrekt sind, müssen Sie für diejenigen, die dies in IISNODE zum Laufen bringen möchten, auch angeben

<configuration>
    <system.webServer>
        <httpErrors existingResponse="PassThrough"/>
    </system.webServer>
<configuration>

in Ihrer web.config (andernfalls frisst IIS Ihre Ausgabe).

Laktak
quelle
2
Danke dir!!! Sie sind der einzige im Internet, der das zu wissen scheint (oder zumindest teilt)! Prost
André Lucas
1

Sie können Fehler nach Inhaltstyp behandeln

Zusätzlich Behandlung nach Statuscode.

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

Wenn Sie res.format verwenden können, können Sie einfachen Fehlerbehandlungscode schreiben.

Empfehlung res.format()statt res.accepts().

Wenn der 500-Fehler im vorherigen Code auftritt, if(500 == err.status){. . . }wird aufgerufen

멍개 -mung
quelle
1

Hallo, bitte finde die Antwort

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}!`));
Krishnamoorthy Acharya
quelle
0

Wenn Sie ein Express-Generator-Paket verwenden:

next (err);

Dieser Code sendet Sie an die 404 Middleware.

Josué Díaz
quelle
0

So senden Sie eine benutzerdefinierte Seite:

app.get('*', function(req, res){
  if (req.accepts('html')) {
     res.send('404', '<script>location.href = "/the-404-page.html";</script>');
     return;
  }
});
Kristian
quelle
0

Ich habe den folgenden Handler verwendet, um 404-Fehler mit einer statischen .ejsDatei zu behandeln.

Fügen Sie diesen Code in ein Routenskript ein und fordern Sie ihn file.jsdann app.use()in Ihrem app.js/ server.js/ an www.js(wenn Sie IntelliJ für NodeJS verwenden).

Sie können auch eine statische .htmlDatei verwenden.

//Unknown route handler
 router.get("[otherRoute]", function(request, response) {
     response.status(404);
     response.render("error404.[ejs]/[html]");
     response.end();
 });

Auf diese Weise antwortet der laufende Express-Server mit einer richtigen Antwort, 404 errorund Ihre Website kann auch eine Seite enthalten, auf der die 404-Antwort des Servers ordnungsgemäß angezeigt wird. Sie können auch eine umfassen navbar, dass 404 error templatedie Links zu anderen wichtigen Inhalte Ihrer Website.

Mudrak Patel
quelle
0

Wenn Sie von Ihren Funktionen (Routen) zu Fehlerseiten umleiten möchten, gehen Sie wie folgt vor:

  1. Fügen Sie allgemeinen Code für Fehlermeldungen in Ihre app.js ein -

    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. In Ihrer Funktion können Sie anstelle einer Fehlerseitenumleitung zuerst den Fehlerstatus festlegen und dann next () verwenden, damit der Codefluss den obigen Code durchläuft.

    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()
    }
Anshul Bisht
quelle
0

Die 404-Seite sollte unmittelbar vor dem Aufruf von app.listen eingerichtet werden. Express unterstützt * in Routenpfaden. Dies ist ein Sonderzeichen, das zu allem passt. Dies kann verwendet werden, um einen Routenhandler zu erstellen, der allen Anforderungen entspricht.

app.get('*', (req, res) => {
  res.render('404', {
    title: '404',
    name: 'test',
    errorMessage: 'Page not found.'
  })
})
Rajat
quelle
0

Abdeckung aller HTTP-Verben in express

Um alle HTTP-Verben und alle verbleibenden Pfade abzudecken, können Sie Folgendes verwenden:

app.all('*', cb)

Die endgültige Lösung würde so aussehen:

app.all('*', (req, res) =>{
    res.status(404).json({
        success: false,
        data: '404'
    })
})

Sie sollten nicht vergessen, den Router am Ende zu setzen. Weil die Reihenfolge der Router wichtig ist.

NGS
quelle
0

Der obige Code hat bei mir nicht funktioniert.

Also habe ich eine neue Lösung gefunden, die tatsächlich funktioniert!

app.use(function(req, res, next) {
    res.status(404).send('Unable to find the requested resource!');
});

Oder Sie können es sogar auf einer 404-Seite rendern.

app.use(function(req, res, next) {
    res.status(404).render("404page");
});

Hoffe das hat dir geholfen!

John Tasci
quelle
-3
app.get('*',function(req,res){
 res.redirect('/login');
});
s srinivas
quelle