Bagaimana cara mengarahkan 404 kesalahan ke halaman di ExpressJS?

203

Saya tidak tahu fungsi untuk melakukan ini, apakah ada yang tahu tentang fungsi ini?

hexacyanide
sumber

Jawaban:

274

Saya menemukan contoh ini cukup membantu:

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

Jadi sebenarnya bagian ini:

// "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
sumber
Silakan tentukan "ditangani"? Apa sebenarnya yang menandai rute yang ditangani?
Timo Huovinen
1
Saya kira tidak ada rute yang cocok yang ditemukan sampai saat itu.
Felix
2
FYI, penggunaan app.routersekarang sudah tidak digunakan lagi. Lihat github.com/strongloop/express/wiki/…
iX3
2
Untuk respons JSON mungkin lebih baik digunakan res.jsondaripada res.send(). Mereka akan berperilaku sama dalam kode Anda tetapi menggunakan res.jsonakan melakukan beberapa keajaiban dalam objek konversi otomatis ke string di mana .send()tidak. Lebih baik aman daripada menyesal. expressjs.com/api.html#res.json
wgp
9
Sekarang pertanyaan ini muncul di FAQ expressjs.com/starter/faq.html#how-do-you-handle-404s-
Ivan Fraixedes
157

Saya pikir Anda harus terlebih dahulu menentukan semua rute Anda dan sebagai tambahan rute terakhir

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

Contoh aplikasi yang berfungsi:

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
sumber
6
Yah ... masalahnya adalah "*" sudah cocok dengan file .js dan .css, dan mereka tidak ditentukan dalam aplikasi ... well, saya tidak tahu apakah ada beberapa cara untuk menangkap persis hal yang sama dengan kesalahan 404, atau cara untuk menimpa pesan "Tidak bisa mendapatkan ...". Bagaimanapun, terima kasih
1
Apakah Anda menggunakan middleware statis, karena Anda masih dapat menyajikan file statis?
Alfred
4
app.get('/public/*', function(req, res){ res.sendfile(__dirname + '/public/' + req.url); })Anda dapat menggunakan rute ini untuk mengirim file statis. berfungsi dengan baik dengan rute "*" di atas. app.use(express.static(__dirname + '/public'));tidak bekerja untuk saya, kabel.
Chris
25
Ini tidak bekerja untuk saya, tetapi kemudian saya menemukan bahwa saya app.use(express.static(...))datang setelah app.use(app.router). Setelah saya beralih mereka semua baik-baik saja.
Stephen
5
+1 untuk menambahkan komentar @ Stephen pada jawaban Anda. Ini juga tidak bekerja untuk saya sampai saya meletakkan app.use (app.router) SETELAH app.use (express.static (...))
braitsch
37

Anda bisa meletakkan middleware di posisi terakhir yang menimbulkan NotFoundkesalahan,
atau bahkan merender halaman 404 secara langsung:

app.use(function(req,res){
    res.status(404).render('404.jade');
});
Ganesh Kumar
sumber
9
Tolong pertimbangkan sedikit jawaban yang lebih jelas di lain waktu ... Contohnya biasanya baik - dan ini adalah contoh yang baik - tetapi beberapa penjelasan bisa sangat, sangat baik juga ...
Tonny Madsen
2
+1 Sangat bagus! Saya pikir ini lebih baik daripada rute terakhir, karena dengan begitu Anda tidak harus ke use()Anda app.routerpada saat terakhir. (seperti dalam kasus saya)
Alba Mendez
Selain itu, ini menggantikan perilaku default pada setiap permintaan (tidak hanya GETs). Coba ke POSTURL acak dengan metode lain; itu akan mengembalikan default Cannot POST.... Penyerang kemudian akan tahu Anda menggunakan Express.JS.
Alba Mendez
Sangat bagus kecuali menggunakan ejs Anda hanya harus meletakkanres.render('404')
locrizak
Ini mungkin juga harus memiliki status (404) res.status (404) .render ('404')
MartinWebb
32

Jawaban di atas bagus, tetapi di setengahnya Anda tidak akan mendapatkan 404 karena kode status HTTP Anda dikembalikan dan di setengah lainnya, Anda tidak akan dapat membuat templat render kustom. Cara terbaik untuk memiliki halaman kesalahan khusus (404) di Expressjs adalah

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

Tempatkan kode ini di akhir semua pemetaan URL Anda.

Sushant Gupta
sumber
@SushantGupta - Apa yang Anda maksud dengan 'pemetaan URL eksistensial yang valid?'
Jonathan Bechtel
@ JonathanBechtel Seperti memiliki blok kode di atas setelah rute URL Anda tidak salah.
Sushant Gupta
6

Pada baris terakhir app.js, cukup masukkan fungsi ini. Ini akan menggantikan halaman kesalahan tidak ditemukan halaman default:

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

Itu akan mengesampingkan semua permintaan yang tidak memiliki penangan yang valid dan membuat halaman kesalahan Anda sendiri.

Vivek Bajpai
sumber
2
Komentar "baris terakhir app.js" Anda yang membantu! Terima kasih!
C0NFUS3D
Menambahkan fitur ke aplikasi saya. Terima kasih :)
Pramesh Bajracharya
5

Jawaban atas pertanyaan Anda adalah:

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

Dan ada artikel bagus tentang mengapa ini adalah cara terbaik di sini .

Marius Cotofana
sumber
1
Apa perbedaan antara senddan end?
Timo Huovinen
Saya pikir dia telah salah menulissend
Zaid abu khalaf
4

express-error-handler memungkinkan Anda menentukan template khusus, halaman statis, atau penangan kesalahan untuk kesalahan Anda. Ia juga melakukan hal-hal penanganan kesalahan bermanfaat lainnya yang harus diterapkan oleh setiap aplikasi, seperti melindungi dari serangan DOS kesalahan 4xx, dan shutdown yang anggun pada kesalahan yang tidak dapat dipulihkan. Inilah cara Anda melakukan apa yang Anda minta:

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

Atau untuk penangan khusus:

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

Atau untuk tampilan khusus:

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

Ada beberapa kasus di mana halaman 404 tidak dapat ditulis untuk dieksekusi sebagai rute terakhir, terutama jika Anda memiliki fungsi routing yang tidak sinkron yang membawa / rute terlambat ke pesta. Pola di bawah ini mungkin diadopsi dalam kasus-kasus itu.

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
sumber
2
Cemerlang, terima kasih! Satu-satunya jawaban (?) Yang tidak bergantung pada pemrosesan linear express (yaitu, "letakkan saja pengendali kesalahan di akhir").
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
sumber
2

Cara termudah untuk melakukannya adalah dengan menangkap semua untuk Halaman Kesalahan

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

Kemudian

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

Sekarang Anda dapat menyimpan semua halaman "html" Anda (termasuk halaman "html" kesalahan) dalam sebuah variabel

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

Sekarang Anda cukup memanggil halaman menggunakan Metode Get dan dapatkan semua untuk setiap rute yang tidak tersedia untuk mengarahkan ke halaman kesalahan Anda menggunakan 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);
});

Jangan lupa untuk mengatur Port dan Dengarkan server:

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

Ini sekarang akan menampilkan halaman kesalahan Anda untuk semua titik akhir yang tidak dikenal!

Kean Amaral
sumber
1

Meskipun jawaban di atas benar, bagi mereka yang ingin ini berfungsi di IISNODE Anda juga perlu menentukan

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

di web.config Anda (jika tidak, IIS akan memakan output Anda).

laktak
sumber
2
Terima kasih!!! Anda adalah satu-satunya di internet yang tampaknya tahu itu (atau setidaknya membagikannya)! Cheers
André Lucas
1

Anda dapat menangani kesalahan sesuai dengan tipe konten

Selain itu, penanganan sesuai dengan kode status.

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

Jika Anda dapat menggunakan res.format, Anda dapat menulis kode penanganan kesalahan sederhana.

Rekomendasi res.format()bukanres.accepts() .

Jika kesalahan 500 terjadi pada kode sebelumnya, if(500 == err.status){. . . }dipanggil

멍개 -ung
sumber
1

Hai tolong temukan jawabannya

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
sumber
0

Jika Anda menggunakan paket generator ekspres:

selanjutnya (err);

Kode ini mengirim Anda ke middleware 404.

Josué Díaz
sumber
0

Untuk mengirim ke halaman khusus:

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

Saya menggunakan pengendali di bawah ini untuk menangani kesalahan 404 dengan .ejsfile statis .

Menempatkan kode ini dalam naskah rute dan kemudian mengharuskan file.jsmelalui app.use()di Anda app.js/ server.js/www.js (jika menggunakan IntelliJ untuk NodeJS)

Anda juga dapat menggunakan .htmlfile statis .

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

Dengan cara ini, server ekspres yang berjalan akan merespons dengan benar 404 errordan situs web Anda juga dapat menyertakan halaman yang menampilkan respons 404 server dengan benar. Anda juga bisa memasukkan navbardalam 404 error templateyang link ke konten penting lain dari situs Anda.

mudrak patel
sumber
0

Jika Anda ingin mengarahkan ulang ke halaman kesalahan dari fungsi Anda (rute) maka lakukan hal-hal berikut -

  1. Tambahkan kode pesan kesalahan umum di app.js Anda -

    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. Dalam fungsi Anda, alih-alih menggunakan redirect halaman kesalahan, Anda dapat menggunakan mengatur status kesalahan terlebih dahulu dan kemudian menggunakan next () agar aliran kode melewati kode di atas -

    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
sumber
0

Halaman 404 harus disiapkan tepat sebelum panggilan ke app.listen.Express memiliki dukungan untuk * di jalur rute. Ini adalah karakter khusus yang cocok dengan apa pun. Ini dapat digunakan untuk membuat pengendali rute yang cocok dengan semua permintaan.

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

Mencakup semua kata kerja HTTP dalam express

Untuk mencakup semua kata kerja HTTP dan semua jalur yang tersisa, Anda dapat menggunakan:

app.all('*', cb)

Solusi akhir akan terlihat seperti ini:

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

Anda tidak boleh lupa untuk menempatkan router pada akhirnya. Karena urutan router penting.

NGS
sumber
0

Kode di atas tidak berfungsi untuk saya.

Jadi saya menemukan solusi baru yang benar-benar berfungsi!

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

Atau Anda bahkan dapat merendernya menjadi halaman 404.

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

Semoga ini bisa membantu Anda!

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