node.js:数据库查询 +多部分表单数据锁定

发布于 2024-11-15 02:36:04 字数 2336 浏览 1 评论 0原文

我对整个节点的事情仍然相当陌生,所以如果这非常愚蠢,请原谅我,但是:

如果我在 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 "[email protected]" http://localhost:8080/test

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

我是个十足的白痴吗?这不是正确的做事方式吗?

I'm still reasonably new to the whole node thingie, so please forgive me if this is rampantly stupid, but:

If I call query() on a node-mysql client object, I can no longer get the body of a request object from within my web app (express).

my basic POST / PUT pattern requests requiring user auth is:

_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);
         });
      }
   });
});

Now, the problem is that the get_request_body function simply never comes back. It seems as though it's just "blocked" on teh request object.

Here is a sample program:

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);
        });
    }
}

The trick: It only fails if I'm using multipart form POST data, not regular POST data:

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

works

curl -u un:pw -X POST -F "[email protected]" http://localhost:8080/test

locks up and never returns. I've seen the same error with connect-form and multipart-js. Kind of stumped here now.

Am i a complete idiot? Is this not the correct way of doing things?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别闹i 2024-11-22 02:36:04

我认为当您将 end 侦听器添加到请求对象时,end 事件已经触发。您需要立即将 IO 事件侦听器添加到主 app.post 函数作用域中的 req 对象,而不是在数据库查询返回时添加到异步回调中。这是一个包含一些日志语句的版本,显示了导致此问题的事件序列。底部的 req.emit('end'); 只是一个 hack,用于证明请求被锁定的原因。您的 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
    }
}

I think by the time you add your end listener to the request object, the end event has already fired. You need to add your IO event listeners to the req object immediately in the main app.post function scope, not in an async callback when your DB query returns. Here's a version with some log statements that show the sequence of events causing this issue. The req.emit('end'); at the bottom is just a hack to prove why the request is locking up. Your end event handler never gets called, but synthesizing a duplicate end event does allow the request to complete (but the body has not been properly parsed).

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文