所以,我查看了其他具有相同错误的答案,但他们的解决方案都没有回答我的问题。
我有一个包含 ~10k 个名称的 mysql 表,我有一个 nodejs 文件的 25 个实例(侦听不同的端口),每个实例都发送一个请求,通过 php 文件从数据库中获取 400 个名称。如果我将请求设置为抓取 100 - 150,它可以工作,但如果我告诉它获取超过 200,我会收到错误"意外的输入结束"。
这是我的nodejs请求:
function user_acquire()
{
var request = require('request');
var http = require('http');
var post_options = {
host: 'localhost',
path: '/name_request.php?pos1=50&pos2=150', //this is where the amount to request is set & range
method: 'POST',
headers: {
'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded',
}
};
// Set up the request
var post_req = http.request(post_options, function (res) {
res.on('data', function (chunk) {
usernames = JSON.parse(chunk);
});
});
post_req.end();
}
这是nodejs与之通信的php文件:
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "test";
$conn = new mysqli($servername, $username, $password, $dbname, '3306');
if ($conn->connect_error)
{
die("Connection failed: " . $conn->connect_error);
}
$start = $_GET['pos1'];
$end = $_GET['pos2'];
$sql = mysqli_query($conn, "SELECT * FROM preliminary_tests WHERE ID BETWEEN '$start' AND '$end'");
$array = mysqli_fetch_all($sql, MYSQLI_ASSOC);
print_r(json_encode($array,JSON_UNESCAPED_UNICODE));
?>
使用 JSON_UNESCAPED_UNICODE
并不能解决问题。我知道 mysql 是用 utf-8
编码的。这两个函数都适用于较小的请求,但增加请求大小会破坏一个,我不确定为什么
在 200+ 用户名之后,响应变得太大,并在发送到节点时被分成多个块。看起来您在到达时正在解析每个块,但可能是该块过早地切断了 JSON,这就是您收到错误的原因。您应该能够在到达时将每个块附加到响应的"data"事件中,并在响应的"end"事件中解析它们。
这看起来像这样:
// Set up the request
var post_req = http.request(post_options, function (res) {
// create an enclosure for usernames
// so it's in scope in both callbacks,
// and instantiate it as an empty string:
var usernames = "";
// append each chunk on arrival:
res.on('data', function (chunk) {
usernames += chunk;
});
// at the end of the response, parse the full set of chunks:
res.on('end', function() {
usernames = JSON.parse(usernames);
// do something with the parsed usernames
});
});
post_req.end();
看看 MDN 或 CodeSchool 上的闭包,因为当你想在回调之间共享范围时,它们是一个有用的工具。
此外,请查看 Node 的 HTTP Response 的"块"和"结束"事件的文档,以了解更多使用它们的方法。
更新:这是关于SO关闭的一个很好的解释。
您可能会
有这种行为,因为它们将变量传递$start和$end。在当前情况下,查询正在数据库中查找字符串,但大多数情况下 ID 可能是整数。这可能解释了这种行为。
如果像我假设的那样,则将两个变量转换为:
$start = (int)$_GET['pos1'];
$end = (int)$_GET['pos2'];
,然后将 SQL 更改为 :
"SELECT * FROM preliminary_tests WHERE ID BETWEEN $start AND $end"