js兼容浏览器的iframe加载完事件

在网页中点击某个按钮或链接下载文件的时候,从点击到文件开始下载的过程中有一个过程,如果没有对这个过程进行判断的话,用户会一直不停地进行点击,体验非常差。浏览器没有办法直接获取到下载文件的事件,一个讨巧的方法是可以使用iframe的onload事件,代码如下:

 代码如下 复制代码

 var url = "http://www.111cn.net";
 var iframe = document.createElement('iframe');
 iframe.src = url;
 iframe.style.display = 'none';
 iframe.onload = function() {
     console.debug('start downloading...');
     document.body.removeAttribute(iframe);
 }
 document.body.appendChild(iframe);

这段代码在Firefox下面可以正常获取到onload的事件,但在Google Chrome和IE下面,如果iframe src属性的链接是一个网页的话,可以触发onload事件,但如果HTTP文件头中包含Content-disposition: attachment…即下载文件的链接的话,不会触发这个事件。浏览器对iframe具体的支持情况可见:Events to expect when dynamically loading iframes in javascript。

这一点有点可惜,有人提出了一个利用Cookies的思路,即在服务器端捕获文件下载的进度,然后随时将进度写入到Cookies中,前台javascript轮询Cookies,从而得到文件是否开始进行下载。这种方案详细的可以参考:Detecting the File Download Dialog In the Browser,后台如果使用Spring的话可以通过过滤器来判断文件下载的情况,

。我们需要借助threadlocal来实现线程安全。

 代码如下 复制代码
@Override 
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler) throws Exception { 
        if(usePerformance){ 
            StopWatch stopWatch = new StopWatch(handler.toString()); 
            stopWatchLocal.set(stopWatch); 
            stopWatch.start(handler.toString()); 
        } 
         
        return true; 
    } 
 
 
 @Override 
    public void afterCompletion(HttpServletRequest request, 
            HttpServletResponse response, Object handler, Exception ex) 
            throws Exception { 
        if(usePerformance){ 
            StopWatch stopWatch = stopWatchLocal.get(); 
            stopWatch.stop(); 
            String currentPath = request.getRequestURI(); 
            String queryString  = request.getQueryString(); 
            queryString = queryString == null ? "":"?" + queryString; 
            log.info("access url path:" + currentPath + queryString +  " |time:" + stopWatch.getTotalTimeMillis()); 
            stopWatchLocal.set(null); 
        } 
         
    } 

 
呵呵,如果你没有使用springMVC可以使用filter来完成

 代码如下 复制代码
stopWatch.start(); 
 
doFilterChain(); 
stopWatch.stop(); 

但这种方案实施起来需要后台进行配合,前后台的代码都过于复杂,另外如果浏览器将Cookies功能关闭的话就会出错,后来无意中在Google Chrome下面运行这个Plunker代码,发现可以正常捕获iframe加载后的时间。原始代码是使用的AngularJS,代码如下:

 代码如下 复制代码

 var url = 'https://www.111cn.net';
 var e = angular.element("<iframe id=export style='display:none'></iframe>");
 e.attr('src', url);
 e.load(function() {
     console.debug('start downloading...');
 });
 
 angular.element('body').append(e);

这里使用了element的load事件,即页面实际加载DOM元素的事件。但非常奇怪的是,如果我将上述代码中的url换成其他的下载文件之后依然无法激活这个事件。后来仔细分析对比了二者中的HTTP Response Header的差异,发现需要在服务器端增加下面两个HTTP头文件内容即可:

 代码如下 复制代码
 response.addHeader("X-Content-Type-Options", "nosniff");
 // 提示浏览器不让其在frame或iframe中加载资源的文件内容 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/X-Frame-Options
 response.addHeader("X-Frame-Options", "deny");

如果使用jQuery的话,javascript代码如下:

 代码如下 复制代码

 var url = 'https://github.com/blueimp/jQuery-File-Upload/archive/master.zip';
 var e = $("<iframe id=export style='display:none'></iframe>");
 e.attr('src', url);
 e.load(function() {
     console.debug('start downloading...');
 });
 
 $('body').append(e);

时间: 2024-10-11 00:19:42

js兼容浏览器的iframe加载完事件的相关文章

JS获取浏览器语言动态加载JS文件示例代码

 项目出于多语言版本的考虑,前台使用easyui,通过获取浏览器语言版本,来相对的加载easyui语言包,easyui默认语言包en-US 代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script type="text/javascript">  //ie  if (navigator.browserLanguage != "undefined" && navigator.browserLanguage

JS获取浏览器语言动态加载JS文件示例代码_javascript技巧

项目出于多语言版本的考虑,前台使用easyui,通过获取浏览器语言版本,来相对的加载easyui语言包,easyui默认语言包en-US 代码如下 <script type="text/javascript"> //ie if (navigator.browserLanguage != "undefined" && navigator.browserLanguage != null) { if (navigator.systemLangu

javascript 广告后加载,加载完页面再加载广告_javascript技巧

先加载完页面再加载广告的原理: 网页打开的顺序都是按页面从上到下的顺序加载完成的,所以要想使广告不影响页面打开速度,就要等页面全部打开完成后,再加载JS代码.等页面加载完再加载广告其实就是将广告的 JS 代码放在页面的底部,等页面内容打开完成后再加载到广告代码,再用页面上预留好的的 DIV 输出广告. 使用方法: 1.将以下代码放置页面中想要放广告的地方 复制代码 代码如下: <div id="myads">载入中-</div> 2.将一下代码放置页面底部,也就

iframe 调用远程问题如何实现B完全加载完远程页面后A再刷新

问题描述 iframe 调用远程问题如何实现B完全加载完远程页面后A再刷新 A页面<iframe 调用远程页面B,如何实现B完全加载完远程页面后A再刷新? 我原代码这样的, <script type="text/javascript"> document.write('<div id="gd_cn"><span>正在加载内容,请稍候--</span><img src="../images/ajax

自定义require函数让浏览器按需加载Js文件_javascript技巧

前言 本文介绍的是自定义require函数让浏览器实现按需加载Js文件,那到底要怎么自己写一个按需加载的库呢 为了实现按需加载: //这是我们要实现的功能,require('str.js')时加载str.js文件,并创建一个叫str对象,等加载完毕之后执行str对象的ready方法里的函数. var str = require('str.js'); str.ready(show); //要执行的函数 function show(res){ console.log(res); } //str.js

网站加载完以后浏览器一直还是加载状态

问题描述 网站加载完以后浏览器一直还是加载状态 我把页面删得只剩下最后一个jquery的文件, 在刷新十次以上也会出现这个问题. 如果页面文件过多的话出现的频率会更高. 一般两分钟后抱错如下: net::ERR_CONTENT_LENGTH_MISMATCH 每次都是不同的文件请求中出现这个的错误

JS iFrame加载慢怎么解决_javascript技巧

在项目中经常要动态添加iframe,然后再对添加的iframe进行相关操作,有时候会遇到iframe加载很慢什么原因呢,该如何解决呢?带着这个问题一起通过本文学习,寻找答案吧! aaa.html <HTML> <HEAD> <TITLE>aaa</TITLE> </HEAD> <BODY> <IFRAME src="bbb.html" name=bbb width="100%" heigh

javascript广告延迟加载代码或页面内容加载完后加载Js调用内容

 代码如下 复制代码 <!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.111cn.net/1999/xhtml"> <head> <meta http-equiv=

java-Ext.ux.IFrame页面还没加载完loadMask已经结束了这是为什么

问题描述 Ext.ux.IFrame页面还没加载完loadMask已经结束了这是为什么 如题,loadMask结束时页面并没有加载完成,还会有一段空白时间,请问怎么设置让loadMask在页面加载完才消失 解决方案 http://www.fengfly.com/plus/view-213235-1.html 解决方案二: iframe加载的内容是不是ajax动态加载的?如果是不好控制,因为一般是window.onload后mask就会隐藏,ajax异步加载不算在onload里面的,自己看下有没有