gpt4 book ai didi

javascript - Node Express 中的 res.sendfile 以及传递数据

转载 作者:IT老高 更新时间:2023-10-28 22:03:38 24 4
gpt4 key购买 nike

有没有办法从 Node.JS 应用程序重定向到 HTML 文件,例如:res.sendFile表达并将 JSON 数据传递给 html 文件?

最佳答案

我知道这已经晚了,但我想提供一个没有其他人提供的解决方案。此解决方案允许将文件流式传输到响应,同时仍允许您修改内容,而无需模板引擎或将整个文件缓冲到内存中。

如果你不关心“为什么”

,请跳到底部

让我首先描述一下为什么 res.sendFile 对于那些不知道的人来说如此受欢迎。由于 Node 是单线程的,它通过连续执行大量非常小的任务来工作 - 这包括从文件系统读取和回复 http 请求。 Node 在任何时候都不会停止它正在做的事情并从文件系统中读取整个文件。它会读一点,做点别的,再读一点,做点别的。回复 http 请求和 Node 中的大多数其他操作也是如此(除非您明确使用操作的 sync 版本 - 例如 readFileSync - 如果您能提供帮助,请不要这样做,认真,不要 - 这是自私的)。

假设有 10 个用户请求同一个文件。低效的做法是将整个文件加载到内存中,然后使用 res.send() 发送文件。即使它是同一个文件,该文件也会在发送到浏览器之前分别加载 10 次到内存中。然后垃圾收集器需要在每次请求后清理这些困惑。代码会天真地写成这样:

app.use('/index.html', (req, res) => {
fs.readFile('../public/index.html', (err, data) => {
res.send(data.toString());
});
});

这似乎是正确的,并且有效,但效率极低。因为我们知道 Node 以小块的形式做事,所以最好的办法是在从文件系统中读取小块数据时将它们发送到浏览器。这些 block 永远不会存储在内存中,您的服务器现在可以处理更多数量级的流量。这个概念称为流式传输,这就是 res.sendFile 所做的 - 它将文件从文件系统直接流式传输给用户,并为更重要的事情腾出内存。如果您要手动操作,它的外观如下:

app.use('/index.html', (req, res) => {
fs.createReadStream('../public/index.html')
.pipe(res);
});

解决方案

如果您希望在对文件进行轻微修改的同时继续将文件流式传输给用户,那么此解决方案适合您。请注意,这不是模板引擎的替代品,而是用于在流式传输文件时对文件进行小的更改。下面的代码会将一个带有数据的小脚本标签附加到 HTML 页面的正文中。它还展示了如何在 http 响应流中添加或附加内容:

NOTE: as mentioned in the comments, the original solution could have an edge case where this would fail. For fix this, I have added the new-line package to ensure data chunks are emitted at new lines.

const Transform = require('stream').Transform;
const parser = new Transform();
const newLineStream = require('new-line');

parser._transform = function(data, encoding, done) {
let str = data.toString();
str = str.replace('<html>', '<!-- Begin stream -->\n<html>');
str = str.replace('</body>', '<script>var data = {"foo": "bar"};</script>\n</body>\n<!-- End stream -->');
this.push(str);
done();
};

// app creation code removed for brevity

app.use('/index.html', (req, res) => {
fs
.createReadStream('../public/index.html')
.pipe(newLineStream())
.pipe(parser)
.pipe(res);
});

关于javascript - Node Express 中的 res.sendfile 以及传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33027089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com