在开发中遇到一个问题,后台是java,extjs下载文件时,使用了如下代码
window.location.href =_context+"/dynamic/xx/temManage.do?method=downLodadHistory";,这条语句指向一个输出文件流的方法,如果文件不大的话,浏览器的下载框能很快打开,但是一旦文件较大,这个操作就得持续一段时间,csdn上有大侠指点:"可以在页面放置一个隐藏的iframe,添加onload事件在设置iframe的src为下载的url时显示mask,在onload事件中隐藏mask",我是实在没看明白什么意思,请同志们指点一下.
   
   还有就是如果在iframe设置了下载操作,extjs怎么调用呢?

解决方案 »

  1.   

    我一般用window.open将这个下载页面在新窗口打开,然后在弹出的新窗口操作下载。
      

  2.   

    刚才试了下,iframe也无法监控文件是否下载完毕,只要url响应完毕就执行onload事件了。所以直接window.open或者隐藏iframe也行,不过window.open可能会被浏览器拦截请求,隐藏iframe没有这个在页面内插入一个隐藏的iframe,如下,注意修改onload事件中的代码成为隐藏mask的代码
    <iframe src="" id="hiddenIfr" style="display:none" onload="alert('finish')"></iframe>将你原来的js语句改成如下的就行了
    //========启动mask的代码
    //window.location.href =_context+"/dynamic/xx/temManage.do?method=downLodadHistory"
    //==========>
    document.getElementById('hiddenIfr').src=_context+"/dynamic/xx/temManage.do?method=downLodadHistory";
      

  3.   

    showbo 你好,我按照你的指点加了代码,但是,onload事件,是在页面加载时就执行了,等我在extjs中执行下载时,这个事件没有调用哦
      

  4.   


    如果生成文件比较慢,建议你用Ext.Ajax方法调用后台代码生成文件流,文件生成成功后返回成功信息。然后在用window.open()打开那个生成好的文件去下载。比如:var btn = new Ext.button();btn.on('click',function(){
        var mask = new Ext.LoadMask(Ext.getBody(), {   
                    msg : "下载文件中..."  
                });
        mask.show();
        
        Ext.Ajax.request({
            url:'/dynamic/xx/temManage.do?method=downLodadHistory'   //这个文件返回的是文件是否生成成功的信息,如{success:true,url:/upload/1.pdf}
            success:function(response){
                 mask.hide();
                 var response = Ext.decode(response.responseText);
                 if(response.success)
                 {
                       window.open(response.url)        //生成完文件后,将返回信息中的文件地址在新窗口打开。
                 }
                 else
                 {
                       //弹出错误信息
                 }
            },
            failure:function(){
                 mask.hide();
                 //错误处理
            }
        });
    });
      

  5.   


    silvernet 谢谢你,这个方法一开始我也想了,但是,项目要求,不允许在服务器端生成文件,哪怕是临时文件,所以我的url指向的链接,直接生成的是一个流,就是说这个url对应的方法,是一个直接向客户端输出文件字节流的方法……
      

  6.   


    了解,你可以把我的方法与3楼showbo兄的方法结合起来。点击下载按钮的时候,设置一个隐藏的iframe的src为文件的下载地址。当文件流输出完成的时候触发该<iframe>的onload事件,在这个事件里调用方法关闭mask.譬如:var btn = new Ext.button();var panel = new Ext.Panel({
        height:0,
        width:0,
        html:'<iframe id="downloadFrame" src="" id="hiddenIfr" style="display:none" onload="FinishDownload"></iframe>'
    });function FinishDownload(){
        Ext.getCmp('downloadMask').hide();
    }
    btn.on('click',function(){
        var mask = new Ext.LoadMask(Ext.getBody(), {
                    id:'downloadMask,
                    msg : "下载文件中..."  
                });
        mask.show();
        
        document.getElementByID('downloadFrame').src="/dynamic/xx/temManage.do?method=downLodadHistory";
    });
      

  7.   

    silvernet 谢谢你,这是我的代码,可是还是有问题,当浏览器自带的下载框出现时,iframe的onload事件并没有调用,这个事件的调用是在页面一加载的时候执行的,下面是我的部分代码,不晓得哪里出错了
    function FinishDownload(){
         alert("AAA");
         Ext.getCmp('downloadMask').hide();
    }; 
    Ext.onReady(
    function()
    {
        var downLoadHistoryPDF=function()
        {

    if(historyId=="")
    {
    Ext.Msg.alert('警告', '请选择历史记录!');

      return;
    }
    else
    {
     var mask = new Ext.LoadMask(Ext.getBody(), {
                    id:'downloadMask',
                    msg : "下载文件中..."  
                });
         mask.show();
        
         document.getElementById('downloadFrame').src=_context+"/dynamic              /XX/templateManage.do?method=downLodadHistoryToPDF&historyId="+historyId; historyId="";
    }
    }
     }
     var rightClick = new Ext.menu.Menu({
        id:'rightClickCont',
        items: [
            
               {        
                handler: downLoadHistoryPDF,
                text: '导出PDF',
                iconCls: 'download-icon-pdf'
            }
        ]
    });

    function rightClickFn(grid,rowindex,e){
        e.preventDefault();
        var record=grid.getStore().getAt(rowindex);
    historyId=record.get("historyId");
        rightClick.showAt(e.getXY());
    }

    grid.on('rowcontextmenu', rightClickFn);
    var viewport=new Ext.Viewport(
    {
    layout : 'border',
    style : 'border:#024459 2px solid;',
    html:'<iframe id="downloadFrame" src="" id="hiddenIfr" style="display:none" onload="FinishDownload();"></iframe>',
    items : [grid]
    }
    );
    );