百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>JS教程> js兼容浏览器的iframe加载完事件
分享文章到:

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

发布时间:01/15 来源: 浏览: 关键词:
iframe在不同浏览器中要做到兼容也不是一件容易的事情了,今天我们来看一篇关于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);

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有6人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板