如何从Node.js服务器向客户端进行流传输

3

我目前正在尝试发送一个非常长的csv文件,该文件将在浏览器中进行处理。

我希望能够将其流式传输到客户端,因为它超过了字符串大小限制,并且在服务器上也会占用太多内存。

我已经尝试过

app.get('/test', (req, res)=>{
    let csvStream = byline(fs.createReadStream('./resources/onescsv.csv'));

    csvStream.on('data', (line)=>{
        csvStream.pipe(res);
    });

    csvStream.on('end', () => {
        res.render('./test/test', {
            css:['test/test.css'],
            js:['test/test.js']
        })
    })
});

当我执行上述操作时,它会将读取流发送到客户端,但渲染到页面上,这不是我想要的。我希望能够在客户端JavaScript中逐个接收流缓冲区,以便在流到达时处理流,例如将它们放入表格中。我该如何做?
1个回答

4
首先,您不希望在查找要将数据输入响应的相同请求中调用render。您需要分开处理以下步骤:
  1. 呈现页面
  2. 启动流请求
为了呈现页面,请让您的默认路由发送页面HTML。
app.get('/', (req, res) => {
    res.render('./test/test', {
        css: ['test/test.css'],
        js: ['test/test.js']
    });
});

然后对于流媒体,在服务器端调整您的代码,如下所示:
app.get('/api/csv', (req, res) => {
    let stream = fs.createReadStream('./resources/onescsv.csv');
    stream = byline.createStream(stream);
    stream.pipe(res);
    stream.on('end', res.end);
});

在您的客户端上,在默认的HTML页面中,可以在加载时(或连接到按钮按下)触发一个AJAX请求来拉取CSV数据,例如使用jQuery。

$.get('/api/csv', data => {
    // do something with CSV data
});

只有一个问题。当您在jQuery回调函数中访问数据时,它是访问整个变量还是分块访问? - forJ
@serendipity 不,它不会产生这种效果,如果需要这种效果,则需要使用原始的XHR请求- 请参见示例 - James
@James 很好的回答! - user8377060
我正在使用与您的后端完全相同的代码,前端部分我做了$(document).ready(()=>{$.get('/test/api', data=>{console.log(data)}...`但是它说在发送头之后无法发送。 - forJ
当我注释掉API部分时,它可以工作,因此管道肯定出了问题... - forJ
@serendipity 请注意更新,将 sendStatus 更改为 end - 忘记了 sendStatus 将尝试发送标头。 - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接