• h5下载文件,无兼容问题~


    最近写了个页面,打开页面出现文件列表,用户可以下载文件。

    失败方案

    使用a标签进行下载,参考代码如下:

    因为有批量下载的需求,这里将xhr请求单独封装到downloadFile.js中

    // downloadFile.js
    const downloadFile = (url, onProgress, xhrAr) => {
        console.log(url,'urlurl');
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.responseType = 'blob';
            xhrAr.push(xhr) // 存放下载任务
            xhr.onprogress = (event) => {	// 进度条
                onProgress(event);
                // if (event.lengthComputable) {
                //     const percent = Math.round((event.loaded / event.total) * 100);
                //     onProgress(percent);
                // }
            };
    
            xhr.onload = () => {
                if (xhr.status === 200) {
                    const blob = xhr.response;
                    resolve(blob);
                } else {
                    reject(new Error('下载失败'));
                }
            };
    
            xhr.onerror = () => {
                reject(new Error('下载失败'));
            };
    
            xhr.send();
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    页面使用,代码如下:

    const click = () => {
    	list.forEach((item, index) => {	// 文件数组,批量下载
            console.log(item, 'itemitem');
            let url = serverAPIPrefix + item.filePath
     
            const onProgress = (event) => {	// 进度条处理事件
                 console.log(item, 'itemitem');
            };
            downLoadFile(url, onProgress, dlm.currentTaskList).then((blob) => {
                // 处理下载完成的文件
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.download = item.road ? item.road : '护驾文件管理' + Date.now();
                document.body.appendChild(a);
                a.click();
                URL.revokeObjectURL(url);
            }).catch((error) => {
                console.error('下载失败', error);
            });
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    可以看到,就是用了a标签进行下载。

    完成之后pc端没问题,在进行移动端测试时,发现有些浏览器不支持

    浏览器是否可以下载
    safari
    华为自带浏览器
    vivo自带
    oppo自带
    uc浏览器
    qq浏览器
    百度浏览器

    测试如上,具体表现为,创建了下载任务,但进度条一直是0%

    成功方案

    需要后端添加响应头信息,具体可查看 MDN链接

    Content-Disposition: attachment; filename=326.mp4
    filename:下载下来的文件名,可根据下载文件类型自行修改

    在这里插入图片描述

    加上这个响应头后,访问链接就是直接下载,所以我们直接访问链接就可以,无需做其他操作,代码如下:

    	let url =  item.filePath
    	window.open(url)  
     
    
    • 1
    • 2
    • 3

    如果只是单文件下载,直接使用window.open打开url,就会自行执行下载。
    移动端会在浏览器中自行创建下载任务,用户可在浏览器的下载管理中查看

    但是我们还有个需求,就是批量下载,循环setimeout使用window.open?经过测试,也存在浏览器的差异,下载视频下不全,选择了三个视频下载,结果只下载了两个,有的浏览器还是只能下载一个

    list.forEach(item,index)=>{
    		setTimeout(() => {
                window.open(item.url)
            }, index * 1000);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    既然访问链接直接进行下载,我们只需要打开页面就行,window.open也是同理,但是浏览器为了防止开发人员不断打开新页面,所以window.open是禁止循环调用,打开多个页面使用iframe
    代码如下:

    let triggerDelay = 100;
    let removeDelay = 1000;
    this.urlList.forEach((url, index) => {
      this.createIFrame(url, index * triggerDelay, removeDelay);
    });
    
    // 这里是创建iframe的方法
    function createIFrame(url, triggerDelay, removeDelay) {
       //动态添加iframe,设置src,然后删除
       setTimeout(function() {
         var frame = document.createElement("iframe");
         frame.src = url;
         frame.style.display = "none";
         document.body.appendChild(frame);
         setTimeout(function() {
           frame.remove();
         }, removeDelay);
       }, triggerDelay);
     },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    原文链接点击直达

    使用iframe仍有部分浏览器不支持

    浏览器是否支持
    百度浏览器
    UC浏览器
    oppo自带浏览器
    华为自带浏览器
    vivo自带浏览器
    safari
    QQ浏览器

    到这里并未完全解决批量下载文件的功能,如有指教欢迎评论~

  • 相关阅读:
    常用的 Arrays 类方法
    NSSCTF之Misc篇刷题记录(17)
    微服务 Spring Cloud 7,Nacos配置中心的Pull原理,附源码
    web期末网站设计大作业 奶茶店网站美食餐饮网站设计与实现(HTML+CSS+JavaScript)
    02-docker network
    windows mysql安装卸载,多版本mysql方案
    KVM网络环境下vlan和trunk的理解
    相似对角化和约旦标准型求法(附带Matlab代码)
    Pytorch中tensor的数据类型显示和转换方法
    python基于Vue的web信息收集程序设计
  • 原文地址:https://blog.csdn.net/BiangBaing/article/details/133169147