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

Javascript ExtJS 5-从POST servlet请求下载文件,javascript,extjs,extjs4,ria,extjs5,Javascript,Extjs,Extjs4,Ria,Extjs5,我尝试使用表单提交方法在ExtJS5中实现导出功能。我看了下面的stackoverflow链接,它有帮助,但不是完全的 在我的例子中,在请求-响应成功后,我遇到了一个问题,得到了无效的JSON编码错误。甚至我尝试将读取器从JSON读取器更改为其他字符串读取器(在链接中提到),但由于某些原因,它非常成功 代码:- var form = Ext.create('Ext.form.Panel',{ timeout: 60000 }); var basicForm = form.

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

在我的例子中,在请求-响应成功后,我遇到了一个问题,得到了无效的JSON编码错误。甚至我尝试将读取器从JSON读取器更改为其他字符串读取器(在链接中提到),但由于某些原因,它非常成功

代码:-

  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
    Id,Name
    13092,Thiru
    12767,Arasu
    117,Vinod
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');
      }
    }); 
错误消息:-

  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
    Id,Name
    13092,Thiru
    12767,Arasu
    117,Vinod
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');
      }
    }); 
来自Java servlet(CSV)的输出响应:-

  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
    Id,Name
    13092,Thiru
    12767,Arasu
    117,Vinod
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');
      }
    }); 
我认为由于这个编码问题,即使在请求返回200个成功状态之后;浏览器下载窗口未弹出!非常感谢您的帮助,提前感谢

我修改了下面的代码,但是浏览器下载仍然没有发生,尽管响应是200

使用Iframe/Form修改代码:-

  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
    Id,Name
    13092,Thiru
    12767,Arasu
    117,Vinod
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');
      }
    }); 
注意:我正在使用谷歌浏览器


谢谢

您是否有任何响应头配置

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

您有响应的任何头配置吗

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

导出可以通过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
    }    
}

导出可以通过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
    }    
}

使用不可见表单和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();
  }
});

使用不可见表单和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();
  }
});

当您尝试使用另一个客户端时,您的Javaservlet是否正确地返回文件?(例如针对Chrome的高级REST客户端)是的,是的,是Francis!看一看:我想你需要一个IFRAME。@FrancisDucharme:我试图添加一个IFRAME/表单,但浏览器弹出窗口仍然没有出现。修改并添加了上面相同的代码!有人能帮我解决这个问题吗?当您尝试使用另一个客户机时,您的Java servlet是否正确返回文件?(例如针对Chrome的高级REST客户端)是的,是的,是Francis!看一看:我想你需要一个IFRAME。@FrancisDucharme:我试图添加一个IFRAME/表单,但浏览器弹出窗口仍然没有出现。修改并添加了上面相同的代码!有人能帮我解决这个问题吗?所有添加到servlet请求中的头文件,它不仅仅发生在ExtJS(迁移框架)中。它仍然可以与我们当前的Tibco GI RIA框架配合使用<代码>HTTP/1.1 200确定日期:2015年3月13日星期五12:41:53 GMT传输编码:分块内容类型:text/csv;charset=UTF-8内容配置:附件;fileName=Report\u RETRIEVECHARACTERISTICTYPE\u 1426250513346.csv SESSIONLOGID:24407011 X-Powered-By:Servlet/2.5 JSP/2.1添加到Servlet请求的所有头,它不仅仅发生在ExtJS(迁移框架)中。它仍然可以与我们当前的Tibco GI RIA框架配合使用<代码>HTTP/1.1 200确定日期:2015年3月13日星期五12:41:53 GMT传输编码:分块内容类型:text/csv;charset=UTF-8内容配置:附件;fileName=Report\u RETRIEVECHARACTERISTICTYPE\u 1426250513346.csv SESSIONLOGID:24407011 X-Powered-By:Servlet/2.5 JSP/2.1这在Chrome中非常有效。但我正在IE 9中寻找解决方案。如果你也能帮我的话!!您好,我可以使用extdirecturl(@ExtDirectMethod(ExtDirectMethodType.SIMPLE)),而不是URL中的RESTURL吗?这在Chrome中非常有用。但我正在IE 9中寻找解决方案。如果你也能帮我的话!!您好,我可以使用extdirecturl(@ExtDirectMethod(ExtDirectMethodType.SIMPLE)),而不是URL中的RESTURL吗?