Fetch可以做请求的进度监控吗?

 先自问自答:fetch 原生做不到请求的进度监控。fetch 是基于 Promise 的,在Promise的世界里,它的结果只有成功或者失败,没有说成功了百分之几或者失败了百分之几的说法。

如果使用Fetch想实现进度监控功能,可能需要结合使用ReadableStreamTransformStream等Web Streams API,或者考虑使用第三方库来辅助实现。

一、简单实现进度监控

我们在发送请求之前,使用如FormDataBlob等对象来包装文件或数据,并通过监听这些对象在发送过程中的变化来间接获取上传进度。但这种方法并不直接由fetch API 提供,实现起来较为复杂。

这里我们使用一个较新的API来试试。ReadableStream 支持流式处理数据,可以逐块读取数据,我们可以用它来实现一个文件流的进度。
ReadableStream

      // fetch请求进度监控
      async function fetchWithProgress(url, onProgress) {
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`请求异常: ${response.status}`);
        }

        const reader = response.body.getReader();
        let totalBytesReceived = 0;

        const contentLength = parseInt(
          response.headers.get("content-length") || 0
        );

        return new ReadableStream({
          start(controller) {
            function push() {
              reader.read().then(({ done, value }) => {
                if (done) {
                  controller.close();
                  return;
                }
                totalBytesReceived += value.length;
                onProgress(totalBytesReceived, contentLength);
                controller.enqueue(value);
                push();
              });
            }
            push();
          },
        });
      }

      // 示例
      fetchWithProgress("https://example.com/large-file", (loaded, total) => {
        console.log(
          `下载进度: ${Math.round((loaded / total) * 100)}%`
        );
      }).then((stream) => {
        // 处理stream
        const writer = new WritableStream({
          write(chunk) {
            // 处理chunk
            console.log(`接受chunk大小: ${chunk.length} bytes`);
          },
        });

        stream.pipeTo(writer);
      });

二、使用第三方库实现进度监控

  1. axios
import axios from 'axios';

axios.request({
    method: 'GET',
    url: 'http://localhost:3000/file',
    responseType: 'stream',
    onDownloadProgress: function(progressEvent) {
        const percentCompleted = Math.round((progressEvent.loaded / progressEvent.total) * 100);
        console.log(`下载进度: ${percentCompleted}%`);
    }
}).then(response => {
    // 处理响应
});
  1. fetch-progress
import fetchProgress from 'fetch-progress';

fetchProgress('http://localhost:3000/file', (progress) => {
    console.log(`下载进度: ${progress.percent}%`);
}).then(response => {
    // 处理响应
});

三、XHR的进度监控

如果不严格要求使用fetch API,可以考虑使用XMLHttpRequest,它原生支持上传和下载的进度事件,可以直接使用XMLHttpRequest对象的onprogress事件来跟踪上传进度。

      // fetch请求进度监控
      function downloadWithProgress(url, onProgress) {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url, true);
        xhr.responseType = "blob";

        // 监听下载进度
        xhr.onprogress = function (event) {
          if (event.lengthComputable) {
            const percentComplete = Math.round(
              (event.loaded / event.total) * 100
            );
            onProgress(percentComplete);
          }
        };

        // 监听加载完成
        xhr.onload = function () {
          if (xhr.status === 200) {
            console.log("下载完成!");
          } else {
            console.error("下载异常:", xhr.status);
            throw new Error(`下载异常: ${xhr.status}`);
          }
        };

        // 监听错误
        xhr.onerror = function () {
          console.error("请求错误!");
          throw new Error("请求错误!");
        };

        // 监听超时
        xhr.ontimeout = function () {
          console.error("请求超时!");
          throw new Error("请求超时!");
        };

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

      // 示例用法
      downloadWithProgress("http://localhost:3000/file", (progress) => {
        console.log(`下载进度: ${progress}%`);
      });

 总结:如果需要做请求的进度监控,在没有强制一点要使用Fetch的情况下,还是老老实实使用XHR吧,或者使用成熟的第三方请求库,比如axios等,它该有的功能都有了。

### 回答1: A: Ajax 是一种用于创建异步网页应用程序的技术,它使用 XMLHttpRequest 对象来与服务器交换数据。Axios 是一个基于 promise 的 HTTP 客户端,可以用在浏览器和 node.js 中。Fetch API 是一个更新的新的网络 API,用于替代 XMLHttpRequest(XHR)并提供更多的功能。 ### 回答2: Ajax、axios和fetch都是用于在前端发送异步请求的技术,但在实现方式和特点上有一些不同。 首先,Ajax是一种传统的前端请求技术,通过XMLHttpRequest对象实现异步通信。它能够实现高度的定制性,可以自由设置请求头、请求方式、数据格式等,但使用起来相对复杂,需要手动处理回调函数、状态码等。 而axios是一个基于Promise的HTTP客户端,可以在浏览器和Node.js环境中使用。它封装了XMLHttpRequest对象,提供了更简洁、易用的API,并对请求、响应进行了拦截器处理,可以全局统一处理请求错误、请求超时等。axios还支持取消请求上传进度监控等功能,广泛应用于前端开发中。 fetch是浏览器内置的原生API,用于发送HTTP请求。它是基于Promise的、基于标准的API,采用了更现代的使用方式,相对于Ajax来说更简洁、易用。但fetch在低版本浏览器中不兼容,需要进行处理,并且没有像axios那样提供丰富的功能,如请求拦截、超时等。 综上所述,Ajax是传统的前端请求技术,axios是一种基于Promise的根据封装的HTTP客户端,而fetch是浏览器内置的原生API。在实际使用中,可以根据具体需求选择合适的技术。 ### 回答3: Ajax、Axios和Fetch都是用于进行HTTP请求的工具或技术。 1. Ajax是一种基于原生JavaScript编写的异步请求技术。它通过XMLHttpRequest对象来发送请求并与服务器进行通信,可以实现数据的异步更新,无需刷新整个页面。然而,Ajax的API相对复杂,需要手动处理一些细节,如错误处理和请求取消。 2. Axios是一个基于Promise的HTTP客户端,可以在浏览器和Node.js中使用。它封装了XMLHttpRequest对象,提供了更简洁、易用的API,支持GET、POST等HTTP请求方法,并提供了拦截器等功能,方便进行请求和响应的拦截、处理和转换。Axios还可以设置超时时间、防止CSRF攻击等。 3. Fetch是现代浏览器提供的内置API,也是一个基于Promise的HTTP客户端,用于进行网络请求。相比于Axios和Ajax,Fetch的API更简洁,支持链式调用,使用起来更加灵活。Fetch自带了许多功能,如CORS(跨域资源共享)、请求和响应拦截等,还可以通过抛出错误来处理网络请求失败等情况。但是,Fetch在旧版本浏览器中不被支持,需要通过Polyfill或转换工具来兼容。 总结来说,Ajax是一种传统的异步请求技术,Axios和Fetch则是现代的HTTP客户端工具。Axios相对于Ajax提供了更强大、易用的API,在浏览器和Node.js中均可使用;Fetch更加简洁,是现代浏览器内置的API,但在兼容性方面需注意。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值