ExtJS 5 - 从POST servlet请求下载文件

时间:2015-03-12 14:47:01

标签: javascript extjs extjs4 ria extjs5

我尝试使用表单提交方法在ExtJS 5中实现导出功能。我看了下面的stackoverflow链接,它有帮助,但不完全。

Extjs 4 (with a code for 3.4 below) downloading a file returned from a post request

在我的情况下,我在请求响应成功后遇到问题,得到无效的JSON编码错误。甚至我试图将读取器从JSON读取器更改为其他一些字符串阅读器(在链接中提到),但它非常成功某种原因。

http://www.sencha.com/forum/showthread.php?86704-handling-xml-response-on-form-submit

代码: -

  var form = Ext.create('Ext.form.Panel',{
    timeout: 60000
  });
  var basicForm = form.getForm();
  basicForm.errorReader= new String();
    basicForm.submit({
        url     :  GRID_EXPORT_URL,
        method  : 'POST',
        headers : {
            "USER": user,
            "SERVERSESSIONID": serverSessionId,
            "Content-Type":"application/x-www-form-urlencoded"
        },  
        params  : {
            gridId:"dummyGrid",
            colDescs:"col1,Name"
        },              
        scope   : this,
        success : function(responseText){              
        },
        target: '_blank' 
    });  

错误消息: -

   [E] Ext.JSON.decode(): You're trying to decode an invalid JSON String: Code

来自Java servlet(CSV)的输出响应: -

    Id,Name
    13092,Thiru
    12767,Arasu
    117,Vinod

我认为由于这个编码问题,即使请求返回200成功状态;浏览器下载窗口没有加速!非常感谢您的帮助,提前谢谢!

我已经修改了类似下面的代码,但是虽然响应是200,但浏览器下载仍然没有发生。

使用iframe / Form修改代码: -

onClickExport : function(){
    var body = Ext.getBody();
    var downloadFrame = body.createChild({
         tag: 'iframe',
         cls: 'x-hidden',
         id: 'app-upload-frame',
         name: 'uploadframe'
     });      
    var downloadForm = body.createChild({
         tag: 'form',
         cls: 'x-hidden',
         id: 'app-upload-form',
         target: 'app-upload-frame'
     });        
    Ext.Ajax.request ({
      url     : EXPORT_URL,
      method  : 'POST',
      form    : downloadForm,       
      timeout : 30 * 60 * 1000, // 30 Minutes should be OK.
      scope   : this,
      headers : {
            "USER": user,
            "SERVERSESSIONID": serverSessionId,
            "Content-Type":"application/x-www-form-urlencoded"
      },  
      params  : {
            gridId:"dummyGrid",
            colDescs:"col1,Name"
      }, 
      success : function (r) {
        alert("Success");
      },
      failure: function(r) {
        alert('error');
      }
    }); 

注意:我使用的是谷歌浏览器浏览器!

谢谢!

3 个答案:

答案 0 :(得分:3)

导出可以通过ajax调用实现,从响应中创建一个Blob并使用msSaveBlob进行保存。这适用于现代浏览器ie10及以上

onClickExport: function() {
    CUIF.Ajax.request({
        url: '......',
        method: 'POST',
        scope: this,
        params: {
           ...
           ...
         },
        success: function(data,response) {
            this.onExportSuccess(response);
        }
    });
},

onExportSuccess: function(response){
     this.getView().unmask("Loading...");
     var disposition = response.getResponseHeader('Content-Disposition');
     var filename = disposition.slice(disposition.indexOf("=")+1,disposition.length);
     var type = response.getResponseHeader('Content-Type');
     var blob = new Blob([response.responseText], { type: type });
     if (typeof window.navigator.msSaveBlob !== 'undefined') {
        // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created These URLs will no longer resolve as the data backing the URL has been freed."
        window.navigator.msSaveBlob(blob, filename);
     } 
     else {
        var URL = window.URL || window.webkitURL;
        var downloadUrl = URL.createObjectURL(blob);
        if (filename) {
            // use HTML5 a[download] attribute to specify filename
            var a = document.createElement("a");
            // safari doesn't support this yet
            a.href = downloadUrl;
            a.download = filename;
            document.body.appendChild(a);
            a.click();
        } 
        setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
    }    
}

答案 1 :(得分:0)

您是否有响应的标头配置?

header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=file.csv");
// Disable caching
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: 0"); // Proxies

答案 2 :(得分:0)

使用隐形窗体和0高度iframe创建一个这样的Sencha OnPostDownloader组件。

Ext.define('MyApp.view.OnPostDownload', {
  extend: 'Ext.Component',
  alias: 'widget.OnPostDownloader',
  autoEl: {
    tag: 'iframe',
    cls: 'x-hidden',
    src: Ext.SSL_SECURE_URL
  },
  postAndDownload: function (config) {
    var invsibleForm = Ext.create('Ext.form.Panel', {
      title: 'invsibleForm',
      standardSubmit: true,
      url: config.url,
      timeout: 120000,
      height: 0,
      width: 0,
      hidden: true,
      items: [ {
        xtype: 'hiddenfield',
        name: 'mydata',
        value: config.params
      } ]
    });

    invsibleForm.getForm().submit();
  }
});