当前位置: 首页 > 知识库问答 >
问题:

前端 - fetch下载文件读取进度,提示只能读取一次?

邓俊材
2023-08-08
 useEffect(() => {    const videoRef = $('.home_bg_logo_box_video_1')[0] as HTMLVideoElement;    const videoURL = 'video/0.mp4';    // 加载视频完成后再播放    fetch(videoURL).then((response: any) => {      const contentLength = response.headers.get('Content-Length');      const fileSizeBytes = parseInt(contentLength, 10);      let downloadedBytes = 0;      const reader = response.body.getReader();      function readChunk() {        reader.read().then(({ value, done }: any) => {          if (done) {            console.log('done', response.body);            // TODO 读取不到blob            return;          }          downloadedBytes += value.length;          const progress = (downloadedBytes / fileSizeBytes) * 100;          setPre(Math.floor(progress));          readChunk();        });      }      readChunk();    });    // .then((blob: Blob) => {    // init(blob());    // });    function init(blob: Blob) {      videoRef.src = URL.createObjectURL(blob);      // 当浏览器预计能够在不停下来进行缓冲的情况下持续播放指定的音频/视频时,会发生 canplaythrough 事件。      videoRef.addEventListener('canplaythrough', () => {        $('.home_bg_logo_box_loading').css({          // display: 'none',        });        videoRef.play();      });      videoRef.addEventListener('ended', function () {        // 播放结束后的操作 从第N秒开始播放        videoRef.currentTime = 8;        videoRef.play();      });    }  }, []);

进度条可以获取到,但是我获取不到blob了。提示错误 TypeError: Failed to execute 'blob' on 'Response': body stream already read。

共有1个答案

乐正意智
2023-08-08

你这个错误是因为HTTP响应体只能被读一次,用ReadableStream的pipeThrough()方法试试:

fetch(videoURL).then(response => {  const contentLength = response.headers.get('Content-Length');  const fileSizeBytes = parseInt(contentLength, 10);  let downloadedBytes = 0;  const transformer = new TransformStream({    transform(chunk, controller) {      downloadedBytes += chunk.length;      const progress = (downloadedBytes / fileSizeBytes) * 100;      setPre(Math.floor(progress));      controller.enqueue(chunk);    }  });  const blobStream = response.body.pipeThrough(transformer);  return new Response(blobStream, { headers: response.headers }).blob();}).then(blob => {  init(blob);});

MDN

 类似资料:
  • 问题内容: 我正在为具有许多Flash文件的网站制作Greasemonkey脚本。我想对闪存进行哈希处理,问题是闪存文件最大为10 MB。 这很慢;我希望只能获取要散列的前80KB。最终结果将是一种将某些包含有害内容的Flash文件列入黑名单的简便方法。我的脚本如何仅抓取文件的前80 KB(或大约80 KB)? 问题答案: 发送的头在你的AJAX请求。 例如: (对于与目标页面位于同一域中的文件。

  • fetch 方法允许去跟踪 下载 进度。 请注意:到目前为止,fetch 方法无法跟踪 上传 进度。对于这个目的,请使用 XMLHttpRequest,我们在后面章节会讲到。 要跟踪下载进度,我们可以使用 response.body 属性。它是 ReadableStream —— 一个特殊的对象,它可以逐块(chunk)提供 body。在 Streams API 规范中有对 ReadableStr

  • 问题内容: 我可以从文件中读取内容,并且能够通过更改for循环中的数字来更改行数,但是我不希望那样并排显示文件中的所有数字。我需要它们全部一一随机掉下来。 问题答案: 我想你要打印的是 仅显示此列表(可能包含100条)中的前20条随机行

  • 与malloc'相同大小的内存和手动读取整个文件到malloc'区域相比,这有什么不同?

  • 本文向大家介绍vue实现文件上传读取及下载功能,包括了vue实现文件上传读取及下载功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了vue实现文件上传读取及下载的具体代码,供大家参考,具体内容如下 文件的上传利用input标签的type="file"属性,读取用FileReader对象,下载通过创建a标签实现 关于vue.js的学习教程,请大家点击专题vue.js组件学习教程、Vu

  • 工作表列表 全量读取 游标读取 跳过指定行 忽略空白单元格 忽略空白行 忽略跳过动作常量 设置全局读取类型 单元格回调模式读取 数据类型读取 数据类型常量