Ajax 无刷新下载文件

这是最近做项目时遇到的一个小问题,在此记录一下解决方案,以备后用。

需求分析

  1. 项目中供用户下载的文件是实时生成的,而生成文件需要一定时间。在服务端生成文件并返回结果前不希望用户看到的是一个空白页面。
  2. 下载的文件是需要权鉴的。为防止文件“被”泄露,因此,不能在文件生成之后直接返回一个文件的 URL 给客户。
  3. 希望用户就停留再当前页面。

心路历程

看到这个需求,第一时间想到的就是 Ajax ,但是后来发现 Ajax 支持的返回数据类型有 xml, json, script, or html,貌似并不支持“流”类型。因此开始苦思解决方案。

然后想到了 iframe ,iframe 内的动作“不会影响”父页面状态。然后就开始着手解决问题。

解决问题

  1. 先发一个 Ajax 请求到服务器(判断是否 Ajax 请求,区分操作),要求生成文件(输出文件)。
  2. 返回生成结果。
  3. 向页面内添加一个 iframe 和 form ,并把 form 的 target 设置为 iframe。
  4. 提交 form。

然后就自动开始下载文件了,全程无刷新。

一些代码

$.ajax({
   url: url,
   type: 'POST',
   dataType: 'json',
   data: data...,
})
.done(function( data ) {
   if( data.s == 200 ){
       if( $('#down-box').length > 0 ){
           $('#down-box').remove();
       }
       $('body').append('<div id="down-box"><iframe name="downloadFrame" style="display: none;" frameborder="0"></iframe>'+
       '<form id="downForm" action="url" method="post">'+
       '<input type="hidden" name="action" value="down-service">'+
       ...
       '</form></div>');
       $('#downForm').attr("target","downloadFrame");
       $('#downForm')[0].submit();
       ... 
   }else{
       ...
   }
})
.fail(function() {
    ...
});
分享