js网络进度监控

前端做网络请求是基于AJAX的,Ajax有两种方式:

  • XMLHttpRequest: 简称XHR,比较常用的axios就是基于XMLHttpRequest封装的

  • fetch:新的api,它相对应的第三方库是umi-request

浏览器原生的就支持这两种请求。其他库都是基于这两种去封装的。

xhr_fetch.png

fetch文档比较中可以看出来,它无法实现请求进度的监控,因为fetch是基于promise的,promise只有成功和失败,所以进度监控是难以处理的。

XMLHttpRequest进度监控

function xhr_request(options={}) {
    const {url, method='GET', onProgress, data=null} = options;
    return new Promise(async (resolve, reject)=> {
        const xhr = XMLHttpRequest();
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onreadystatechange = ()=> {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    resolve(xhr.responseText);
                  } else {
                    reject({status: xhr.status, message: '请求失败'})
                  }
            }
        }
        // xhr.onprogress = onProgress;
        // 或
        xhr.addEventListener('progress', e => {
            console.log(e.loaded, e.total);
            onProgress &&
            onProgress({
                loaded: e.loaded,
                total: e.total
            });
        });
        
        //监控文件上传的进度
        // xhr.upload.onprogress = onProgress;
        // 或
        xhr.upload.addEventListener('progress', onProgress);
        // 建立请求连接
        xhr.open(method, url);
        // 发送请求,data则为请求参数
        xhr.send(data);
    });
    
}

fetch进度监控

function fetch_request(options={}) {
    const {url, method='GET', onProgress, data=null} = options;

    return new Promise(async (resolve)=> {
        const resp = await fetch(url, {
            method,
            body: data
        });
        // 获取总的数据量
        const total = +resp.headers.get('content-length');
        const decoder = new TextDecoder();
        let body = '';
        // 获取数据流的读取器
        const reader = resp.body.getReader();
        let loaded = 0;
        while(1) {
            // value是buffer类型
            const {done, value} = await reader.read();
            if(done) {
                // 数据读取完成则退出循环
                break;
            }
            loaded += value.length;
            // buffer解码
            body += decoder.decode(value); 
            onProgress && onProgress({loaded, total});
        }
        resolve(body);
    });
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容