使用 Node,如何使用 Connect 处理 Data/End/Error 事件?

Using Node, how do I handle Data/End/Error events with Connect?

我一直致力于学习 Node,并创建了一个可用的 Web 服务器,例如:

var server = http.createServer(function (req, res) {
    var data = "";

    req.on("data", function (d) {
        data += d;
    });

    req.on("end", function () {
        // process code
        var html = ...
        res.writeHead(200, { "Content-Type": "text/html" });
        res.end(html);
    });

    req.on("error", function () {
        // handle error
    });
});

server.listen(3000); // port
console.log("127.0.0.1:" + server.address().port); // localhost:port

扩展我的知识,我正在使用 Connect 和其他一些模块:

var http = require("http");

var bodyParser = require("body-parser"); // parse request body - req.body
var cookieParser = require("cookie-parser"); // parse cookie header - req.cookies
var session = require("express-session"); // user session - req.session (uses cookies)

var connect = require("connect");
var app = connect();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(session({ secret: "shhh, it's a secret", resave: true, saveUninitialized: true }));

app.use(function (req, res, next) {
    var data = "";
    req.on("data", function (d) {data += d;});
    req.on("end", function () {...});
    req.on("error", function () {...});
});

var server = http.createServer(app);

server.listen(3000); // port
console.log("127.0.0.1:" + server.address().port); // localhost:port

本质上,我在最后的 app.use() 中使用了 http.createServer() 中的前一个函数。

同样,工作正常...除了...对于我通过提交按钮执行的 POST 请求。

在这种情况下,data/end/error 事件永远不会触发。

我发现,如果我只是忽略 data/end/error 事件,并且基本上只是在我的 app.use() 中编写结束事件的逻辑,那么一切正常,POST 数据通过。

我假设缺少数据事件仍然有效,因为任何 .js 或 .css 文件都足够小,不需要多个块,并且对于我使用的图像 fs.createReadStream。

我没有错误事件,但我还没有遇到真正触发的情况。

我计划稍后深入研究 Connect 和 Express,但不是现在(除非我需要)。 现在想学Node。

所以,我想我的问题是, 使用 Connect (app.use) 时,我该如何正确处理 data/end/error 事件?

不确定这是否是一个完整的答案,但我从 req.on("end") 代码块中移动并修改了它,并将其放在单独的 app.use() 中就在最后一个之前。

app.use(function (req, res, next) {
    var contentType;
    switch (path.extname(url.parse(req.url, true, true).pathname)) {
        case ".css":
            contentType = "text/css";
            break;
        case ".gif":
            contentType = "image/gif";
            break;
        case ".ico":
            contentType = "image/x-icon";
        case ".jpeg":
        case ".jpg":
            contentType = "image/jpg";
            break;
        case ".js":
            contentType = "text/javascript";
            break;
        case ".png":
            contentType = "image/png";
            break;
        default:
            next();
            return;
    }

    res.writeHead(200, { "Content-Type": contentType });
    fs.createReadStream(__dirname + req.url).pipe(res); // async, kind of
});

几乎可以处理所有 non-HTML 文件,因此我不再担心这些文件的数据事件。