QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 181|回复: 0

[HTML/CSS/JS] fetch获取请求进度

[复制链接]

等级头衔

积分成就    金币 : 2851
   泡泡 : 1516
   精华 : 6
   在线时间 : 1305 小时
   最后登录 : 2024-12-7

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老活跃会员

联系方式
发表于 2024-10-17 07:42:40 | 显示全部楼层 |阅读模式
fetch API 本身不直接支持请求进度的监控,但你可以通过使用 ReadableStream 和 Response.body 来间接实现下载进度的跟踪。对于上传进度,fetch 目前没有直接的方法来跟踪。
( D$ a8 X$ j4 N7 o8 U/ w以下是一个使用 fetch 和 ReadableStream 来获取下载进度的示例:( Q5 |+ @/ F5 H/ u# a8 r8 X
function fetchWithProgress(url, onProgress) {
  return fetch(url).then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const contentLength = response.headers.get('Content-Length');
    if (!contentLength) {
      console.warn('Content-Length response header is missing');
    }

    const total = parseInt(contentLength, 10);
    let loaded = 0;

    const reader = response.body.getReader();
    const stream = new ReadableStream({
      start(controller) {
        function read() {
          reader.read().then(({ done, value }) => {
            if (done) {
              controller.close();
              return;
            }
            loaded += value.length;
            if (onProgress) {
              onProgress(loaded, total);
            }
            controller.enqueue(value);
            read();
          }).catch(error => {
            console.error('Stream reading error:', error);
            controller.error(error);
          });
        }
        read();
      }
    });

    return new Response(stream, { headers: response.headers });
  });
}

// 使用示例
fetchWithProgress('https://example.com/large-file.zip', (loaded, total) => {
  console.log(`Progress: ${loaded} / ${total}`);
}).then(response => {
  return response.blob();
}).then(blob => {
  // 处理下载的 blob
}).catch(error => {
  console.error('Fetch error:', error);
});
在这个示例中,我们使用 ReadableStream 来读取响应流,并在每次读取时更新进度。onProgress 回调函数会被调用,并传入已加载的字节数和总字节数(如果可用)。这种方法适用于监控下载进度,但对于上传进度,你可能需要使用 XMLHttpRequest。
' i- c( ~( O5 W* O( [  @8 r
function uploadFile(file) {
  const xhr = new XMLHttpRequest();

  // 监听上传进度事件
  xhr.upload.addEventListener('progress', (event) => {
    if (event.lengthComputable) {
      const percentComplete = (event.loaded / event.total) * 100;
      console.log(`Upload progress: ${percentComplete.toFixed(2)}%`);
    }
  });

  // 监听下载进度事件
  xhr.addEventListener('progress', (event) => {
    if (event.lengthComputable) {
      const percentComplete = (event.loaded / event.total) * 100;
      console.log(`Download progress: ${percentComplete.toFixed(2)}%`);
    }
  });

  // 请求完成时的事件
  xhr.addEventListener('load', () => {
    if (xhr.status === 200) {
      console.log('Upload complete!');
    } else {
      console.error('Upload failed!');
    }
  });

  // 请求错误时的事件
  xhr.addEventListener('error', () => {
    console.error('Request error!');
  });

  // 设置请求方法和目标URL
  xhr.open('POST', 'your-upload-url-here');

  // 发送请求
  xhr.send(file);
}

// 使用示例
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file) {
    uploadFile(file);
  }
});
ReadableStream3 @% ~" C/ B2 h: L3 w' r
Stream API 中的 ReadableStream 接口表示可读的字节数据流。Fetch API 通过 Response 的属性 body 提供了一个具体的 ReadableStream 对象。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-12-7 07:32

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表