Node.js 如何从express.static检测404错误
我使用Node.js 如何从express.static检测404错误,node.js,express,Node.js,Express,我使用express.static提供静态文件,如下所示: ['/images','/packages','/scripts','/stylesheets'].forEach(p => { app.use(p, express.static(siteSettings.publicFolder + p)); }); 这很好,但是,当请求不存在的文件时,express会按预期引发错误,但这会影响我的自定义错误捕获所有路由: // error handler app.use(functio
express.static
提供静态文件,如下所示:
['/images','/packages','/scripts','/stylesheets'].forEach(p => {
app.use(p, express.static(siteSettings.publicFolder + p));
});
这很好,但是,当请求不存在的文件时,express会按预期引发错误,但这会影响我的自定义错误捕获所有路由:
// 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错误(例如,图像文件)将向客户端返回完整的错误文档(26kb),这似乎是个坏主意
有什么方法可以让我找到导致错误的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');
}
但我在寻找类似的东西:
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');
}
有什么方法可以做到这一点吗?请参阅
有一个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();
});
正如我在评论中所说,您可以将所有工作委托给nginx并返回自定义页面。这是一个快速而干净的解决方案,但您失去了在express中记录此尝试的选项(但您可以在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,因此创建两个位置块非常理想,一个用于路由到静态文件,另一个用于api(或其他任何内容),并仅在静态文件中返回自定义页面。我尝试过这个选项,它似乎要做的就是将自定义处理程序中的错误命中从
404-notfound
更改为500-NOENT file notfound
。这两种方法都已经遇到了自定义错误块。重新检查文件系统似乎比我原来的解决方案更糟糕,我正在寻找一个更干净的解决方案。我认为如果您想使用类似req.errorFromStatic
的方法,唯一的方法是使用带有文件检查的自定义中间件。但也许您可以在nginx/apache中重载404,并在特定路径上返回带有错误的自定义html页面。您找到其他解决方案了吗?@l2ysho部分,一个混乱的解决方案,我启用了fallthrough,它给出了Enonet错误,我在错误捕获中检查了这些错误,并发送了一个空的404响应,但仍然不理想。