node.js - Node.js http 回显服务器返回 400
问题描述
看看下面的 http 回显服务器示例:https ://repl.it/repls/SlipperyQuickwittedEvent
const http = require('http')
const PORT = 6000
const server = http.createServer((req, res) => {
req.pipe(res)
})
server.listen(PORT)
server.on('listening', () => {
const req = http.request(
{
port: PORT
},
res => {
console.log(res.statusCode)
res.pipe(process.stdout)
res.on('end', () => {
server.close()
})
}
)
req.end('abc')
})
我希望它能够打印200
并abc
在控制台上。相反,它只打印400
,没有别的。
我错过了什么?
解决方案
信不信由你,您的困惑似乎源于对 HTTPGET
请求的根本误解。
似乎 Node 的内置http
符合HTTP/1.1 规范,第 9.3 节归结为GET
请求不应包含消息正文,并且在所述GET
请求正文中发送的任何内容都应该被忽略。(所以来源)
编辑:此行为已在NodeJS 的官方 GitHub 存储库中记录为问题。
在该线程中,注意到底层 HTTP 引擎仍将接受并解析GET
具有Content-Length
相关标头的 HTTP 请求。由于您尚未使用当前代码考虑这一点,因此服务器将发送400 Bad Request
响应代码,因为就服务器而言,发送请求正文以及GET
不带Content-Length
标头的请求实际上是格式错误的请求。
更改您的http.request
构造函数以发送Content-Length
带有GET
请求的标头,底层引擎将接受并解析带有请求的请求正文。
const http = require('http');
const PORT = 6000;
const server = http.createServer((req, res) => {
req.pipe(res);
});
server.on('clientError', (err, socket) => {
console.log(err);
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(PORT);
const responseString = "abc";
server.on('listening', () => {
const req = http.request(
{
port: PORT,
headers: {
'Content-Length': responseString.length
}
},
res => {
console.log(res.statusCode);
res.pipe(process.stdout);
res.on('end', () => {
server.close();
});
}
);
req.end(responseString);
});
要解决有关在调试期间捕获此问题的评论,您可以使用此处理程序(直接来自文档,只需进行最少的修改即可添加错误对象的控制台日志记录)来获取有关响应背后原因的更多信息400 Bad Request
:
server.on('clientError', (err, socket) => {
console.log(err);
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
400
然后,控制台将围绕响应提供更多上下文:
节点 v9.7.1 linux/amd64
{ Error: Parse Error
bytesParsed: 59,
code: 'HPE_INVALID_METHOD',
rawPacket: <Buffer 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f 73 74 3a 36 30 30 30 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 ... > }
400
推荐阅读
- git - Git Checkout - npm run watch - 没有任何改变
- angular - Angular 6:如果“无法匹配任何路线”移动到其他组件
- android - 对于语言环境“ar”(阿拉伯语),还应定义以下数量:少、多、二、零
- gcloud - Cloud ML Engine 无法在命令行中运行,并说找不到有效的 Python 路径
- reactjs - 尝试上传到 s3 时出现“params.Body is required”错误
- sql - 日期格式和提取日期值
- bash - 在函数中使用变量(传入占位符)
- python - 使用 SGD (loss=hinge) 为 SVM 寻找最相关或最重要的特征
- android - Android aar 在项目布局中找不到 ID
- android - 如何为 Google Home 实现门铃?