404エラーをExpressJSのページにリダイレクトする方法


回答:


274

この例はとても役に立ちました:

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

  // default to plain-text. send()
  res.type('txt').send('Not found');
});

「処理される」を定義してください。ルートを処理済みとして正確にマークするものは何ですか?
Timo Huovinen 2013年

1
その時点まで一致するルートが見つからなかったと思います。
フェリックス14

2
参考までに、の使用app.routerは非推奨になりました。github.com/strongloop/express/wiki/…を
iX3

2
JSON応答の場合は、のres.json代わりに使用した方がよい場合がありres.send()ます。これらはコード内でも同じように動作しますが、使用res.jsonすると、オブジェクトを文字列に自動変換するときに魔法がかかります.send()。転ばぬ先の杖。expressjs.com/api.html#res.json
wgp

9
今、この質問はFAQに表示されますexpressjs.com/starter/faq.html#how-do-you-handle-404s-
イワンFraixedes

157

最初にすべてのルートを定義し、最後のルートとして追加する必要があると思います

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

6
まあ...問題は、「*」がすでに.jsおよび.cssファイルと一致し、それらがアプリで指定されていないことです...まあ、正確にキャッチする方法があるかどうかわかりません404エラーと同じこと、または「取得できません...」メッセージを上書きする方法。とにかく、ありがとう

1
静的ミドルウェアを使用していますか?それでも静的ファイルを提供できますか?
アルフレッド

4
app.get('/public/*', function(req, res){ res.sendfile(__dirname + '/public/' + req.url); })このルートを使用して静的ファイルを送信できます。上記の「*」ルートで正常に動作します。 app.use(express.static(__dirname + '/public'));有線では動作しません。
クリス

25
これは私にとってはうまくいきませんでしたが、その後、私app.use(express.static(...))が後に来たことがわかりましたapp.use(app.router)。私がそれらを切り替えると、それはすべてうまくいきました。
スティーブン

5
回答に@Stephenのコメントを追加するための+1。app.use(express.static(...))の後にapp.use(app.router)を配置するまで、これは私にとっても機能しませんでした
braitsch

37

NotFoundエラーをスローする最後の位置にミドルウェアを配置する
か、404ページを直接レンダリングすることもできます。

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

9
次回はもう少し詳細な回答を検討してください...例は通常は問題ありません-これは良い例です-しかし、いくつかの説明は非常に非常に良いこともあります...
Tonny Madsen

2
+1 とても良い!私はそのようにはあなたが持っていないので、これは、最後のルートよりも優れていると思うuse()、あなたのapp.router最後の時間に。(私の場合と同様)
アルバメンデス

さらに、これはすべてのリクエストのデフォルトの動作を置き換えます(GETs だけでなく)。してみてくださいPOST他の方法でランダムなURLを。デフォルトに戻りますCannot POST...。攻撃者は、あなたがExpress.JSを使用していることを知るでしょう。
アルバメンデス

置く必要があるejsを使用する以外は非常に良いres.render('404')
locrizak '18年

これにはおそらくstatus(404)res.status(404).render( '404')もある
はずです

32

上記の回答は適切ですが、これらの半分では、HTTPステータスコードが返されたときに404を取得できません。また、残りの半分では、カスタムテンプレートをレンダリングできません。Expressjsでカスタムエラーページ(404)を作成する最良の方法は、

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

このコードをすべてのURLマッピングの最後に配置します。


@SushantGupta-「有効な存在URLマッピング」とはどういう意味ですか?
Jonathan Bechtel 2017年

@JonathanBechtel同様に、エラーのないURLルーティングの後に上記のコードブロックがあります。
Sushant Gupta 2017

6

app.jsの最後の行に、この関数を配置します。これにより、デフォルトのページが見つからないエラーページが上書きされます。

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

有効なハンドラを持たないすべてのリクエストをオーバーライドし、独自のエラーページをレンダリングします。


2
助けになったのは「app.jsの最後の行」コメントでした。ありがとう!
C0NFUS3D 2016

アプリに機能を追加しました。ありがとう:)
Pramesh Bajracharya 2017


4

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

4

特にパーティに/ routeを遅らせる非同期ルーティング機能がある場合は、404ページを最後のルートとして実行するように書き込むことができない場合があります。これらのケースでは、以下のパターンが採用される可能性があります。

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

2
素晴らしい、ありがとう!expressの線形処理に依存しない唯一の回答(?)(つまり、「エラーハンドラーを最後に置く」)。
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');
  });

2

それを行う最も簡単な方法は、エラーページをすべてキャッチすることです

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

これで、認識されていないすべてのエンドポイントのエラーページが表示されます。


1

上記の答えは正しいですが、IISNODEでこれを機能させたい場合は、以下も指定する必要があります。

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

あなたのweb.configで(そうでなければIISはあなたの出力を食べるでしょう)。


2
ありがとうございました!!!あなたはインターネットで唯一それを知っている(または少なくともそれを共有している)ようです!歓声
アンドレ・ルーカス

1

コンテンツタイプに応じてエラー処理できます

さらに、ステータスコードに従って処理します。

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){. . . }呼び出されました


1

こんにちは答えを見つけてください

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}!`));

0

express-generatorパッケージを使用する場合:

next(err);

このコードは、404ミドルウェアに送信します。


0

カスタムページに送信するには:

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

0

以下のハンドラーを使用して、静的.ejsファイルで404エラーを処理しました。

このコードをルートスクリプトに入れてfile.jsからapp.use()app.js/ server.js/www.js(NodeJSのためのIntelliJを使用している場合)

静的.htmlファイルを使用することもできます。

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

このようにして、実行中のExpressサーバーは適切に応答し、404 errorWebサイトにはサーバーの404応答を適切に表示するページを含めることもできます。ウェブサイトの他の重要なコンテンツにリンクするnavbarを含めることもでき404 error templateます。


0

関数(ルート)からエラーページにリダイレクトする場合は、次のことを行います-

  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()
    }

0

404ページは、app.listen.Expressの呼び出しがルートパスで*をサポートする直前に設定する必要があります。これは何にでもマッチする特殊文字です。これを使用して、すべての要求に一致するルートハンドラーを作成できます。

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

0

のすべてのHTTP動詞のカバー express

すべてのHTTP動詞と残りのすべてのパスをカバーするために使用できます:

app.all('*', cb)

最終的なソリューションは次のようになります。

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

最後にルーターを配置することを忘れないでください。ルーターの順序が重要だからです。


0

上記のコードは私にとってはうまくいきませんでした。

そこで、実際に機能する新しいソリューションを見つけました。

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

これがお役に立てば幸いです!


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.