Как обнаружить 404 ошибки из express.static - PullRequest
3 голосов
/ 26 сентября 2019

Я использую express.static для обслуживания статических файлов, как показано ниже:

['/images','/packages','/scripts','/stylesheets'].forEach(p => {
  app.use(p, express.static(siteSettings.publicFolder + p));
});

Это прекрасно работает, однако, когда запрашивается файл, который не существует, экспресс вызовет ошибку, как и ожидалосьно это касается моего пользовательского маршрута для всех ошибок:

// 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') === 'production' ? {} : err;

  // render the error page
  res.status(err.status || 500);
  res.render('views/error');
});

Это означает, что ошибки файла 404 (например, файлы изображений) возвращают полный документ ошибки клиенту (26 КБ), который выглядит какплохая идея.

Есть ли способ узнать, что express.static вызвал ошибку?

Я думал о том, чтобы сделать что-то вроде:

if (req.path.indexOf("/images") === 0){
    res.send('Not found');
} else {
    res.render('views/error');
}

НоЯ ищу что-то вроде:

if (req.errorFromStatic){
    res.send('Not found');
} else {
    res.render('views/error');
}

Есть ли способ сделать это?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Как я уже говорил в комментариях, вы можете делегировать всю работу на nginx и вернуть свою пользовательскую страницу.Это быстрое и чистое решение, но вы теряете возможность регистрировать эти попытки в экспрессе (но вы можете увидеть, что происходит в фоновом режиме в журналах ошибок nginx).

Пример конфигурации:

server {
   listen                          80;
   server_name                     example.local;
   charset                         utf-8;

   root /path/to/root/folder;

  location / {
           limit_req               zone=ddos burst=30 nodelay;
           proxy_set_header        Host $http_host;
           proxy_set_header        X-Forwarded-For $remote_addr;
           proxy_set_header        X-Forwarded-Protocol $scheme;
           proxy_set_header        X-NginX-Proxy true;
           proxy_pass              http://127.0.0.1:8000;
           proxy_redirect          off;
           proxy_http_version      1.1;

           proxy_intercept_errors  on;
           error_page 404 @errors;

   }

    location @errors {
            # /path/to/root/folder/404.html;
            try_files /404.html =404;
    }
}

В этой настройке вы улавливаете все ошибки 404 и возвращаете пользовательский html, поэтому рекомендуется создать 2 блока местоположения, один для маршрута к статическим файлам, а другойдля API (или любой другой) и вернуть пользовательскую страницу только в статических файлах.

0 голосов
/ 26 сентября 2019

См. Документы для экспресс-статики

. Имеется опция fallthrough, которая будет вызывать next() для несуществующих файлов, поэтому ваш блок обработчика ошибок будет достигнут.

app.use("/public", express.static("/static", {fallthrough: false}));

В вашем случае

['/images','/packages','/scripts','/stylesheets'].forEach(p => {
  app.use(p, express.static(siteSettings.publicFolder + p, {fallthrough: false}));
});

Дополнительно напишите собственное промежуточное ПО.Поместите его выше обработчика ошибок:

var fs = require('fs');

app.use(function (req, res, next) {
    if(['/images', '/packages', '/scripts', '/stylesheets'].includes(req.path)) {
        if (!fs.existsSync(path.join(__dirname, siteSettings.publicFolder, req.originalUrl))) {
            res.send('Not found');
        }
    }
    return next();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...