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

ExtJS 5 - Download file from POST servlet request

本文关键字:请求 下载 文件 servlet POST ExtJS      更新时间:2023-09-26

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

Extjs 4(下面带有 3.4 的代码)下载从 post 请求返回的文件

就我而言,我在请求响应成功后遇到问题,出现无效的 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');
      }
    }); 

注意:我正在使用谷歌浏览器!

谢谢!

导出

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

您是否对响应有任何标头配置?

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

使用不可见的形式和 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();
  }
});