【问题标题】:node.js: database query + multipart form data locks upnode.js:数据库查询+多部分表单数据锁定
【发布时间】:2011-09-14 12:52:53
【问题描述】:

我对整个节点的东西还是相当陌生,所以如果这非常愚蠢,请原谅我,但是:

如果我在 node-mysql 客户端对象上调用 query(),我将无法再从我的网络应用程序中获取请求对象的主体 (express) .

我需要用户身份验证的基本 POST / PUT 模式请求是:

_db_client = connect_to_db_server();
app.post("/some/path", function (req, res) {
    _db_client.query("SELECT * FROM Users WHERE username = ?",
                     [ http_basic_auth.username ], function (err, results) {
      if (err != null || resp == null) {
         res.send("AUTH FAILURE: sorry, you can't do that", 403);
      } else {
         get_request_body(req, function (body) {
            do_something();
            res.send("yay, I'm happy", 200);
         });
      }
   });
});

现在,问题是 get_request_body 函数永远不会返回。似乎它只是在请求对象上“被阻止”了。

这是一个示例程序:

var express = require('express'),
    mysql = require('mysql');

var MySQLClient = mysql.Client;
var client = new MySQLClient();

client.user = 'root';
client.password = '';

client.connect(function(err, res) {
    client.query("USE Gazelle", function (qerr, qresp) {
    });
});

var app = express.createServer(  );
app.use(express.bodyParser());

app.post("/test", function (req, res) {
    client.query('SELECT * FROM Users', function (err, results) {
        get_request_body(req, function (body) {
            console.log("wooo");
            console.log(body);
            res.send("cool", 200);
        });
    });
});


app.listen(8080);


function get_request_body (req, callback) {
    if (req.rawBody != undefined) {
        callback(req.rawBody);
    } else {
        var data = '';
        req.setEncoding('binary');

        req.on('data', function(chunk) {
            data += chunk;
        });

        req.on('end', function() {
            callback(data);
        });
    }
}

诀窍:仅当我使用多部分表单 POST 数据而不是常规 POST 数据时它才会失败:

curl -u un:pw -X POST -d ' { "cat" : "meow" }' http://localhost:8080/test

作品

curl -u un:pw -X POST -F "image_file=@test.jpg" http://localhost:8080/test

锁定并且永远不会返回。我在 connect-formmultipart-js 上看到了同样的错误。现在有点难住了。

我是个彻头彻尾的白痴吗?这不是正确的做事方式吗?

【问题讨论】:

    标签: mysql node.js express multipart


    【解决方案1】:

    我认为当您将end 侦听器添加到请求对象时,end 事件已经触发。您需要在主 app.post 函数范围内立即将 IO 事件侦听器添加到 req 对象,而不是在数据库查询返回时的异步回调中。这是一个带有一些日志语句的版本,这些语句显示了导致此问题的事件序列。底部的req.emit('end'); 只是为了证明请求被锁定的原因。您的 end 事件处理程序永远不会被调用,但合成重复的 end 事件确实允许请求完成(但正文尚未正确解析)。

    var express = require('express');
    var app = express.createServer(  );
    app.use(express.bodyParser());
    
    app.post("/test", function (req, res) {
      req.on('data', function(){
        console.log("data fired but your listener is not yet added");
      });
      req.on('end', function() {
        console.log('end fired but your listener is not yet added');
      });
      setTimeout(function() { //Simulating your async DB query
        console.log("setTimeout finished and fired callback");
            get_request_body(req, function (body) {
                console.log("wooo");
                console.log(body);
                res.send("cool", 200);
            });
          }, 50);
    });
    
    
    app.listen(8081);
    
    
    function get_request_body (req, callback) {
        if (req.rawBody != undefined) {
            console.log('express.bodyParser parsed it already');
            callback(req.rawBody);
        } else {
            console.log('get_request_body going to parse because ' + req.rawBody);
            var data = '';
            req.setEncoding('binary');
    
            req.on('data', function(chunk) {
                console.log('get_request_body got data event');
                data += chunk;
            });
    
            req.on('end', function() {
                console.log('get_request_body parsed it');
                callback(data);
            });
            req.emit('end');//BUGBUG
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 2017-08-20
      • 2018-12-06
      • 2020-09-03
      相关资源
      最近更新 更多