fetch获取请求进度

560c140394099db1e93efeca8d99eeac.png

fetch API 本身不直接支持请求进度的监控,但你可以通过使用 ReadableStream 和 Response.body 来间接实现下载进度的跟踪。对于上传进度,fetch 目前没有直接的方法来跟踪。

以下是一个使用 fetch 和 ReadableStream 来获取下载进度的示例:

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

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);
  }
});

ReadableStream

Stream API 中的 ReadableStream 接口表示可读的字节数据流。Fetch API 通过 Response 的属性 body 提供了一个具体的 ReadableStream 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值