node.js:数据库查询 +多部分表单数据锁定
我对整个节点的事情仍然相当陌生,所以如果这非常愚蠢,请原谅我,但是:
如果我在 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-form 和 multipart-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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为当您将
end
侦听器添加到请求对象时,end
事件已经触发。您需要立即将 IO 事件侦听器添加到主app.post
函数作用域中的req
对象,而不是在数据库查询返回时添加到异步回调中。这是一个包含一些日志语句的版本,显示了导致此问题的事件序列。底部的req.emit('end');
只是一个 hack,用于证明请求被锁定的原因。您的end
事件处理程序永远不会被调用,但合成重复的end
事件确实允许请求完成(但正文尚未正确解析)。I think by the time you add your
end
listener to the request object, theend
event has already fired. You need to add your IO event listeners to thereq
object immediately in the mainapp.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. Thereq.emit('end');
at the bottom is just a hack to prove why the request is locking up. Yourend
event handler never gets called, but synthesizing a duplicateend
event does allow the request to complete (but the body has not been properly parsed).