Node.js 当URL包含尾随反斜杠时,使用快速和静态中间件的节点崩溃

Node.js 当URL包含尾随反斜杠时,使用快速和静态中间件的节点崩溃,node.js,connect,express,Node.js,Connect,Express,我有一个简单的Express服务器,它提供一些静态文件。这是服务器: var express = require('express'); var app = express.createServer(); // Configuration app.configure(function() { app.use(express.bodyParser()); app.use(express.staticCache()); app.use(express.static(__di

我有一个简单的Express服务器,它提供一些静态文件。这是服务器:

var express = require('express');
var app = express.createServer();

// Configuration
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.staticCache());
    app.use(express.static(__dirname + '/public'));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

// 404
app.get('*', function(req, res) {
    res.send('not found', 404);
});

app.listen(3000);
在我的公共目录中有一个名为
index.html
的文件。启动
node app.js
,然后浏览到
localhost:3000/index.html
会按预期显示静态文件。导航到
localhost:3000/ind
localhost:3000/ind\
将按预期显示
404
页面

但是,导航到
localhost:3000/index.html\
(注意后面的反斜杠)会使我的
节点
服务器崩溃,原因是:

stream.js:105
      throw er; // Unhandled stream error in pipe.
        ^
Error: ENOENT, no such file or directory  '/home/bill/projects/app/public/index.html\'

为什么
节点
服务器崩溃,而不是只提供
404
页面?我认为由于该文件不存在,静态中间件将跳过它并将请求传递到路由。我通过创建一个自定义中间件来解决这个问题,如果请求URL中存在尾随的反斜杠,它将返回
404
,但我想知道我是否遗漏了什么。谢谢

这种行为的原因似乎是
fs.stat
fs.createReadStream
处理尾部反斜杠的方式不同

当静态中间件中的字符串
'path/to/public/index.html\\\\
被忽略时(在命令行上运行
stat index.html\
检查名为
index.html
的文件,您必须为
index.html\\
运行
stat index.html\\
)。因此,
fs.stat
认为找到该文件是因为它认为您在请求
index.html
,而不调用下一个中间件处理程序

稍后,该字符串认为它正在查找
index.html\
。它找不到该文件并抛出所述错误


由于函数对反斜杠的处理方式不同,您只能使用一些中间件来过滤掉这些请求。

这种行为的原因似乎是
fs.stat
fs.createReadStream
处理后续反斜杠的方式不同

当静态中间件中的字符串
'path/to/public/index.html\\\\
被忽略时(在命令行上运行
stat index.html\
检查名为
index.html
的文件,您必须为
index.html\\
运行
stat index.html\\
)。因此,
fs.stat
认为找到该文件是因为它认为您在请求
index.html
,而不调用下一个中间件处理程序

稍后,该字符串认为它正在查找
index.html\
。它找不到该文件并抛出所述错误


由于函数对反斜杠的处理方式不同,您只能使用一些中间件来过滤这些请求。

看来这是connect then中的一个错误,因为让每个人编写自定义中间件没有多大意义。尤其是那些不愿意轻易拒绝服务攻击的人。我将提交一个bug。谢谢这个问题现在已经在当前的Connect代码库中修复。看起来这是Connect中的一个bug,因为让每个人编写自定义中间件没有多大意义。尤其是那些不愿意轻易拒绝服务攻击的人。我将提交一个bug。谢谢此问题现已在当前的Connect代码库中修复。