【发布时间】:2021-10-09 16:18:59
【问题描述】:
我有一个关于 http 服务器和管道请求的奇怪情况。
根据我过去的经验,当将 http 服务器的请求对象通过管道传输到某种可写流时,它不包括标头,仅包括有效负载。
然而,今天我写了一些非常简单的代码,出于某种原因,我花了过去 2 个小时试图弄清楚为什么它将标题写入文件(超级混乱!)
这是我的代码:
server = http.createServer((req, res) => {
f = '/tmp/dest'
console.log(`writing to ${f}`)
s = fs.createWriteStream(f)
req.pipe(s)
req.on('end', () => {
res.end("done")
})
})
server.listen(port)
我使用以下curl 命令对此进行测试:
curl -XPOST -F 'data=@test.txt' localhost:8080
这就是我在阅读 /tmp/dest 时得到的:
--------------------------993d19e02b7578ff
Content-Disposition: form-data; name="data"; filename="test.txt"
Content-Type: text/plain
hello - this is some text
--------------------------993d19e02b7578ff--
为什么我会在这里看到标题?我希望它只写有效载荷
我大约一年前写了一个代码,它直接流式传输到一个没有标题的文件,我不明白有什么不同,但是这个成功了:
imageRouter.post('/upload', async(req, res) => {
if(!req.is("image/*")) {
let errorMessage = `the /upload destination was hit, but content-type is ${req.get("Content-Type")}`;
console.log(errorMessage);
res.status(415).send(errorMessage);
return;
}
let imageType = req.get("Content-Type").split('/')[1];
let [ err, writeStream ] = await getWritableStream({ suffix: imageType });
if (err) {
console.log("error while trying to write", err);
return res.status(500).end();
}
let imageName = writeStream.getID();
req.on('end', () => {
req.unpipe();
writeStream.close();
res.json({
imageRelativeLink: `/images/${imageName}`,
imageFullLink: `${self_hostname}/images/${imageName}`
});
});
req.pipe(writeStream);
});
有什么不同?为什么我一年前的代码(最后一个块)在没有表单数据/标题的情况下写入?结果文件只是一个图像,没有文本,但这次(第一个块)在结果文件中显示了 http 标头
【问题讨论】:
-
你看到的是http协议格式的纯内容。这是应该的,这是根据http specification的消息。
-
那我怎样才能只管payload呢?
-
另外,这个答案也是一样的,只有有效载荷应该通过管道传输:stackoverflow.com/a/29199616/1463751(除非我缺少某些东西)
-
不修改源流是不能直接做的。或者,您可以侦听请求事件(例如
on(‘request’, fb))并仅提取那里的主体并将其写入您的输出流。 -
我已经在我过去编写的代码中直接做到了 - 我只是不明白现在有什么不同。我将编辑我的问题以包含我过去编写的没有标题的流式代码