解决如何知道iframe下载完成 #92

简介: 解决如何知道iframe下载完成 #92

问题


当使用iframe作为文件下载的载体时,如何知道文件已经下载完毕,现有的iframe的方法具有兼容性问题,在Chrome、IE下无法监听事件监听文件下载完毕,因为事件本身也是对iframe中的html结构的加载进度监听。onloadonloadonload

const url = 'http://www.example.com/file.zip';
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.display = 'none';
iframe.onload = function() {
    console.log('start downloading...');
    document.body.removeAttribute(iframe);
}
document.body.appendChild(iframe);

当Chrome、IE下时,如果HTTP文件头中包含Content-disposition: attachment;即下载文件的链接的话,不会触发这个事件事件。onload


关于Content-disposition


Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 Content-Disposition为属性名disposition-type是以什么方式下载,如attachment为以附件方式下载disposition-parm为默认保存时的文件名服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,当代码里面使用Content-Disposition来确保浏览器弹出下载对话框的时候。 ,一定要确保没有做过关于禁止浏览器缓存的操作。 代码如下: 不然会发现下载功能在Opera和FireFox里面好好的没问题,在IE下面就是不行。response.addHeader(‘Content-Disposition’, ‘attachment’);response.setHeader(‘Pragma’, ‘No-cache’);response.setHeader(‘Cache-Control’, ‘No-cache’); response.setDateHeader(‘Expires’, 0);


解决1:利用Cookie


Nginx配置如下:

add_header Set-Cookie "fileDownloaded=1; path=/;" always;

后端将文件下载进度放在Cookie中,通过轮询Cookie的方式,对文件下载进度进行获取,判断文件是否已经下载完毕。

let link = document.createElement('iframe');
link.src = '/your/file/path/name.zip';
link.style.display = 'none';
document.body.appendChild(link);
let timer = setInterval(() => {
    // 通过判断是否有这个cookie来确定是否下载完成
    if (Cookies.get('fileDownloaded')) {
        console.log('下载完成啦');
        clearInterval(timer);
        document.body.removeChild(link);
        Cookies.remove('fileDownloaded');
    }
}, 500);`

缺陷:

  1. 需要后端配合
  2. 如果客户端禁用了Cookie,则该方案完全失效;在无痕浏览模式下,读取Cookie,甚至代码报错。

解决2:轮询监听readyState


定时器轮询监听readyState的状态,如果是 complete 或者 interactive 说明文件加载完成。

let iframe = document.createElement('iframe');
iframe.src = path;
iframe.style.display = 'none';
document.body.appendChild(iframe);
const timer = setInterval(() => {
    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    if (iframeDoc.readyState == 'complete' || iframeDoc.readyState == 'interactive') {
        document.body.removeAttribute(iframe);
        clearInterval(timer);
        resolve('success');
    }
}, 1000);

该种方法比较好,因为不需要后端进行配合,且不依赖与Cookie等变量带来的问题,且能实现我们的需求。

目录
相关文章
|
7月前
|
JavaScript 前端开发 小程序
js 实现浏览器下载视频2种方法
js 实现浏览器下载视频2种方法
985 0
|
3月前
|
移动开发 前端开发 JavaScript
使用html-to-image代替html2canvas,结合jspdf实现下载pdf(下载截图下载前端dom元素)
本文介绍了在前端项目中,当使用`html2canvas`遇到问题时,如何使用`html-to-image`库作为替代方案,结合`jspdf`实现将DOM元素生成为PDF文件并提供下载。文章首先讨论了`html2canvas`可能遇到的问题,并提供了该库的使用示例代码。随后,详细介绍了`html-to-image`库的安装和使用方法,展示了如何将DOM元素转换为Canvas,再利用`jspdf`生成PDF文件。最后,文章通过示例代码说明了整个转换和下载的过程,并展示了效果截图。
184 0
|
4月前
|
前端开发 Java Maven
iframe的简单使用
这篇文章通过一个简单的Maven项目示例,演示了如何使用`iframe`标签进行页面跳转和局部数据刷新,以及`a`标签的`target`属性与`iframe`的`name`属性如何配合使用来实现链接在`iframe`中的加载。
iframe的简单使用
|
7月前
|
JSON JavaScript 前端开发
用js脚本下载某书的所有文章
用js脚本下载某书的所有文章
75 0
|
移动开发 资源调度 JavaScript
html2canvas 一个强大的使用js开发的浏览器网页截图工具
html2canvas 一个强大的使用js开发的浏览器网页截图工具
216 0
|
移动开发 JavaScript 搜索推荐
iframe常用
iframe常用
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
235 0
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
|
JavaScript
Layui-admin-iframe通过页面链接直接在iframe内打开一个新的页面,实现单页面的效果
Layui-admin-iframe通过页面链接直接在iframe内打开一个新的页面,实现单页面的效果
813 0
Layui-admin-iframe通过页面链接直接在iframe内打开一个新的页面,实现单页面的效果
|
前端开发 JavaScript
html2canvas实现页面截图并使用axios上传
html2canvas实现页面截图并使用axios上传
495 0
html2canvas实现页面截图并使用axios上传
【ThinkPHP5.1】使用layui的图片上传显示问题
【ThinkPHP5.1】使用layui的图片上传显示问题
620 0
【ThinkPHP5.1】使用layui的图片上传显示问题