ExpressJS에서 404 오류를 페이지로 리디렉션하는 방법은 무엇입니까?


답변:


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

1
그 시점까지는 일치하는 경로가 없다고 생각했습니다.
Felix

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


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 오류와 동일하거나 "Get get ..."메시지를 덮어 쓰는 방법입니다. 어쨌든, 감사합니다

1
정적 파일을 계속 사용할 수 있기 때문에 정적 미들웨어를 사용하고 있습니까?
Alfred

4
app.get('/public/*', function(req, res){ res.sendfile(__dirname + '/public/' + req.url); })이 경로를 사용하여 정적 파일을 보낼 수 있습니다. 위의 "*"경로에서 제대로 작동합니다. app.use(express.static(__dirname + '/public'));유선으로 작동하지 않습니다.
Chris

25
이것은 나를 위해 작동하지 않았지만 나는 내 app.use(express.static(...))뒤를 잇는 것을 발견했습니다 app.use(app.router). 내가 그들을 전환하면 모든 것이 잘 나왔습니다.
Stephen

5
답변에 @Stephen의 댓글을 추가 한 +1 내가 app.use 후에 app.use (app.router) (express.static (...)) 넣을 때까지 두 나를 위해 일을하지 않았다
braitsch을

37

NotFound오류를 발생
시키거나 404 페이지를 직접 렌더링하는 마지막 위치에 미들웨어를 배치 할 수 있습니다 .

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

9
다음에 좀 더 장황한 답변을 고려하십시오 ... 예제는 일반적으로 훌륭합니다. 그리고 이것은 좋은 예입니다. 그러나 일부 설명도 매우 좋습니다.
Tonny Madsen

2
+1 매우 좋습니다! 나는 당신이하지 않아도 그런 식으로하기 때문에이 더 나은 마지막 경로보다 생각하는 use()당신의 app.router마지막 시간. (나의 경우와 같이)
Alba Mendez

게다가 이것은 모든 요청 에 대한 기본 동작을 대체합니다 ( GETs 뿐만 아니라 ). POST다른 방법으로 임의의 URL을 시도하십시오 . 기본값을 반환합니다 Cannot POST.... 그러면 공격자가 Express.JS를 사용하고 있음을 알게됩니다.
Alba Mendez

res.render('404')
ejs

이것은 아마도 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

@JonathanBechtel 잘못된 URL 경로 뒤에 위의 코드 블록이 있습니다.
Sushant Gupta

6

app.js의 마지막 줄 에이 함수를 넣으십시오. 기본 페이지를 찾을 수 없음 오류 페이지가 무시됩니다.

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

유효한 핸들러가없는 모든 요청을 무시하고 고유 한 오류 페이지를 렌더링합니다.


2
도움이 된 것은 "app.js의 마지막 줄"입니다. 감사!
C0NFUS3D

내 앱에 기능을 추가했습니다. 감사합니다 :)
Pramesh Bajracharya


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

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

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
감사합니다!!! 당신은 인터넷에서 그것을 아는 것처럼 보이는 (또는 적어도 그것을 공유하는) 유일한 사람입니다! 건배
André Lucas

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

급행 발전기 패키지를 사용하는 경우 :

다음 (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 error웹 사이트에는 서버의 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

app.listen.Express에 대한 호출이 경로에서 *를 지원하기 직전에 404 페이지를 설정해야합니다. 이것은 어떤 것과도 일치하는 특수 문자입니다. 모든 요청과 일치하는 라우트 핸들러를 작성하는 데 사용할 수 있습니다.

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.