1

I have trying to implement the export functionality in ExtJS 5 using form submit method. And I had look at the following stackoverflow link, it helps but not fully.

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

In my case i facing an issue after the request response is successful, getting invalid JSON encoding error.Even i tried to change the reader from JSON reader to some other string reader(mentioned in link), but it is quite successful for some reason.

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

Code:-

  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' 
    });  

Error Message:-

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

Output response from Java servlet(CSV):-

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

I think because of this encoding issue,even after the request returns 200 success status; the browser download window is not getting poped up! You help is much appreciated, thanks in advance!

I have modified the code something like below, but still the browser download is not happening event though the response is 200.

Modified code with 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');
      }
    }); 

Note: I'm using Google Chrome browser!

Thanks!

Community
  • 1
  • 1

3 Answers3

4

export can be achieved with ajax call, creating a Blob out of the response and saving using msSaveBlob. this works in modern browsers ie10 and above

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
    }    
}
  • This works great in Chrome. But I am looking for a solution in IE 9. If you could help me with that as well!! – Shashi Jul 06 '15 at 09:32
  • Hi , instead of rest URL in url , can i use ext direct url ( @ExtDirectMethod(ExtDirectMethodType.SIMPLE)) ? – Ravi Soni Jun 22 '20 at 10:52
0

Do you have any headers configuration for the response?

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
  • All the headers where added to the servlet request, it is not happening only in ExtJS(migration framework). It is still working fine with our current Tibco GI RIA framework. `HTTP/1.1 200 OK Date: Fri, 13 Mar 2015 12:41:53 GMT Transfer-Encoding: chunked Content-Type: text/csv; charset=UTF-8 Content-Disposition: attachment; fileName=Report_RETRIEVECHARACTERISTICTYPE_1426250513346.csv SESSIONLOGID: 24407011 X-Powered-By: Servlet/2.5 JSP/2.1` – Thirunavukkarasu Muthuswamy Mar 13 '15 at 12:43
0

Create a Sencha OnPostDownloader component like this using invisible form and 0 height iframe.

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();
  }
});
Sanjay Singh
  • 957
  • 10
  • 8