前后端如何实现流式传输数据

星期四, 6月 6, 2024 | 1分钟阅读 | 更新于 星期四, 6月 6, 2024

@

要点

  • 响应标头:res.setHeader("Content-type", "application/octet-stream");
  • 后端需要回传数据的地方以异步的方式write数据res.write(data), 最后res.end(data)
  • 上一步的data内容要与前端达成标记共识,这样前端可以对数据进行判断并展示给用户。
  • 前端通过ajaxonprogress事件(axios里的封装成了onDownloadProgress事件)来间断性获取数据。

后端

后端以express为例

router.get("/download", async (req, res) => {
  //设置流式传输标头
  res.setHeader("Content-type", "application/octet-stream");
  //await异步函数:检查视频
  const stdout1 = await asyncExecCheckVideo(url);

  //省略代码................................

  //回传数据1   
  res.write("message:" + "视频查询完毕,准备下载...");
  const downloadOutput = await asyncExecDownloadVideo(
    videoId,
    (progressStr) => {
      //多次回传数据2:提示前端视频下载进度   
      res.write("progress:" + progressStr);
    }
  );
  //回传数据3:提示前端视频下载完成并转码  
  res.write("message:" + "视频下载完毕,转码中...");
  //转码为m3u8格式的文件
  const transcodeOutput = await asyncExec(videoId);
  
  //回传数据4:完成!
  res.end(
    "data:" +
      JSON.stringify({
        title: videoTitle,
        path: `/${videoId}`,
        filenames: fs.readdirSync(`./files/${videoId}`),
      })
  );
});

前端

//由于回传的数据会渐进式的累加到一块,因此,要记录每次内容的长度len,下次从该处截取出当次的最新内容。
let offset = 0;
downloadVideoByURL(url, ({ event }) => {
    //取出data
    const { responseText } = event.target;

    const content = responseText.substring(offset);
    offset = responseText.length;
    if (content.indexOf("message:") === 0) {
        // message内容
        const uMessage = content.split("message:")[1];
    } else if (content.indexOf("progress:") === 0) {
        //进度内容
        const progress = content.split("progress:")[1];
    }
}).then((res) => {
    if (res.status === 200 && res.data) {
        //最终的data,截取并处理
        const rawSplitData = res.data.split("data:")[1];
        const videoInfo = JSON.parse(rawSplitData);
        console.log(`data:`, videoInfo);
    }
});

效果图

效果图

© 2016 - 2025 Jebben 开发日志&网络随笔

🌱 Powered by Hugo with theme Dream.

关于博主

自我介绍

大家好,我是 Jabin,一名拥有 8 年工作经验的前端工程师。我是一个自学成才的开发者,通过不断学习和实践,积累了丰富的 web 端开发经验以及在 B 端后台管理、监控和 C 端教育、媒体类项目方面的丰富经验。

关于我的技能

我精通多种前端技术,包括但不限于:

  • JavaScript 和 TypeScript:我熟练掌握 JavaScript 和 TypeScript,能够利用它们构建出色的前端应用程序。
  • CSS:我对 CSS 有深入的理解,能够编写出美观、响应式的样式。
  • 前端框架:我熟练使用 Angular、React、Vue 和 Next.js 等前端框架,能够根据项目需求灵活选择并应用合适的技术栈。
  • 前端工具:我熟悉 webpack、Vite 等常用的前端打包工具,以及框架配套的 CLI 工具,能够高效地进行项目开发和部署。
  • 后端技术:我了解服务端语言 Java 和 Node.js,并能够与后端开发人员紧密合作,实现完整的应用程序。
  • 数据库和操作系统:我熟悉 SQL 数据库和 Linux 操作系统的常见操作和命令,能够进行数据库管理和服务器配置。

我的项目经验

我曾主导多个从零到一的项目,参与过数百万 UV 项目的开发,具有丰富的项目开发与团队合作经验。

我对技术充满热情,喜欢钻研新技术和解决复杂的技术问题。我还积极参与开源社区,贡献自己的力量,与各地的开发者共同探索和分享技术前沿。

结语

我是一个对技术认真负责、可靠可靠的人,热爱挑战和创新。我希望通过我的个人网站,与更多志同道合的人分享我的经验和见解,共同推动前端技术的发展和进步。

欢迎来到我的个人网站,期待与您的交流和合作!