【发布时间】:2019-11-03 23:17:59
【问题描述】:
当涉及到响应大 JSON (30-35MB) 的 GET 端点时,我的节点服务器有一个奇怪的行为。
我没有使用任何 npm 包。只是核心 API。
仅在从 Internet 查询服务器时才会发生意外行为,如果从本地网络查询它的行为正常。
问题是服务器在写入内容正文的前 1260 个字节后停止写入响应。它不会关闭连接也不会引发错误。 Insomnia(我用于测试的 REST 客户端)只是声明它收到了 1260B 块。如果我从本地机器查询同一个端点,它会说它收到了更多更大的块(每块几 KB)。
我什至不认为问题是由节点引起的,但是因为我使用的是干净的树莓派(安装了 raspbian,然后安装了节点 v13.0.1),并且我使用的唯一进程是 node.js 我不知道如何找到问题的根源,没有负载均衡器或 Web 服务器的错。公共 IP 似乎还可以,其他所有端点都工作正常(每个请求的回复不到 1260B)
该端点的代码如下所示
const text = url.parse(req.url, true).query.text;
if (text.length > 4) {
let results = await models.fullTextSearch(text);
results = await results.map(async result=>{
result.Data = await models.FindData(result.ProductID, 30);
return result;
});
results = await Promise.all(results);
results = JSON.stringify(results);
res.writeHead(200, {'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'max-age=600'});
res.write(results);
res.end();
break;
}
res.writeHead(403, {'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*'});
res.write("You made an invalid request!");
break;
【问题讨论】:
-
您确定
results包含您所期望的内容吗?有点像网络问题,只有第一个数据包以某种方式发出。 -
我建议查看
res.write()返回值(这可能是false表示尚未发送所有数据)然后注册drain事件以查看 http图书馆认为它最终都被发送了。关于here的详细信息。 -
您还可以为
res.end(callback)注册一个回调,并查看它是否被调用以指示它已全部发送。我还建议您使用console.log(results.length)以确保您确实有您认为的回复长度。 -
为什么在这段代码中使用
break;?这里面是什么结构?它是从什么中爆发出来的?我们能看到更大的代码结构吗?