从nodejs向php发送请求时意外的输入结束


Unexpected end of input when sending request from nodejs to php

所以,我查看了其他具有相同错误的答案,但他们的解决方案都没有回答我的问题。

我有一个包含 ~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"