Extjs 4 (with code below for 3.4) downloading the file returned from the mail request

I saw several questions related to this, but none of them answered my problem. I installed Ext.Ajax.request as follows:

var paramsStringVar = 'param1=1&param2=two&param3=something&param4=etc'; Ext.Ajax.request({ url: '/cgi-bin/url.pl', method:'POST', params:paramsStringVar, timeout:120000, success: function(response, opts){ var objhtml = response.responseText; //content returned from server side console.log(objhtml); } }); 

This request retrieves the relevant content from the backend. One parameter is outputType, which can take the values ​​{html, excel, csv}. When returning html for display, I can process and display it correctly. Now about the problem ...

When I set the outputType parameter to csv or excel, I return the corresponding content as csv or tsv (excel) as requested. BUT, I do not want the content, I want the invitation to download the file (csv or excel). How can I make the browser automatically request a file to download a file instead of just extracting text content in extjs?

Version 4.07, so I can not use only functions 4.1

+4
source share
4 answers

Below is my decision. This is how I work now. The response generates an invitation to load / open based on the response type text / csv. Note that an iFrame or iframe link is not needed. I spent a lot of time sorting out the need for an iFrame, which actually violated my decision. An iFrame download is not required to create an invitation to download. To do this, you need a request (feed) like this, as well as a backend that creates the corresponding csv with the response header text / csv.

 var hiddenForm = Ext.create('Ext.form.Panel', { title:'hiddenForm', standardSubmit: true, url: /cgi-bin/url.pl timeout: 120000, height:0, width: 0, hidden:true, items:[ {xtype:'hiddenField', name:'field1', value:'field1Value'}, // additional fields ] }) hiddenForm.getForm().submit() 

The standardSubmit string is vital

+6
source

There seems to be no bulletproof solution, but there are several approaches that I would try:

1) Use iframe instead of real XHR data for POST on the server, for example. <form action="/something" target="myiframe"> where myiframe is the name your hidden iframe. This way, your form will use an iframe (not your main window) to send data to the configured URL. The server should set the response header as application/octet-stream (or some kind of MIME for binary data), so the browser starts the download. Otherwise (if html is returned in your case) you can just get the iframe body innerHTML and display it to the user in the user interface. Although using an iframe (or new window) instead of XHR does not seem like a better idea, this solution seems to be the most reliable so far (and with better browser support).

Here is a slightly modified example from Ext.form.Basic docs:

 Ext.create('Ext.form.Panel', { title: 'Basic Form', renderTo: Ext.getBody(), width: 350, // Any configuration items here will be automatically passed along to // the Ext.form.Basic instance when it gets created. // *THIS* makes the form use a standard submit mechanism, not XHR /**/standardSubmit: true, // URL to submit to url: 'save-form.php', items: [{ fieldLabel: 'Field', xtype: 'textfield', name: 'theField' }], buttons: [{ text: 'Submit', handler: function() { // The getForm() method returns the Ext.form.Basic instance: var form = this.up('form').getForm(); if (form.isValid()) { // Submit the Ajax request and handle the response form.submit({ success: function(form, action) { Ext.Msg.alert('Success', action.result.msg); }, failure: function(form, action) { Ext.Msg.alert('Failed', action.result.msg); }, // You can put the name of your iframe here instead of _blank // this parameter makes its way to Ext.form.Basic.doAction() // and further leads to creation of StandardSubmit action instance /**/ target: '_blank' }); } } }] }); 

There are two key parameters here (lines marked with /**/ ):

  • standardSubmit: true config, which you submit to your form will make it standard, not XHR.
  • Passing the target parameter to the form submit action. This function is not documented, but you can see that it is used in the Ext.form.action.Submit source code (all the parameters that you pass to the Ext.form.Basic.submit () Method ultimately as parameters to the Ext.form instance .action. *.

In the sample code, I put target: '_blank' to demonstrate that it works immediately (it will create a new browser window). You can replace it with the name of your iframe later, but I suggest that you first check how your form passes data to a regular new window, and then develops the logic that creates and processes the iframe. I think you have to process the result inside the iframe. It's not that complicated, see the implementation of Ext.data.Connection.upload () for an example of iframe processing.

ExtJS actually already uses the iframe method for the uploads file. See Ext.data.Connection and Ext.form.field.Field.isFileUpload () for an understanding of how this might work.

2) Suggested here: Using HTML5 / Javascript to create and save a file .

If you do not want to follow the iframe path, you can try to create a URI of data from the response data and proceed to download using the URI:

 content = "Hello world!"; uriContent = "data:application/octet-stream," + encodeURIComponent(content); window.location.href = uriContent; 

Again, the mimetic is very important here. This worked for me, however you should note that browsers impose a size limit on the data URI (256 Kbps is a safe bet).

3) Another answer in the mentioned topic refers to the FileSaver.js library implements (abandoned?) W3 spec. Use and demo here . It uses [BlobBuilder] to generate blob binary data, which are then used to initialize the download using one of several methods. Although this solution seems to work, it uses legacy APIs and cannot be promising.

+7
source

You do not need to create a form panel and hide it in the extjs file. We can add the html form and click on the button in the extjs file, we can send the form using the URL. This will work in both IE and Chrome browsers. Below is my code that I tried and its work is excellent,

 <form action="<%=fullURL%>/DownloadServlet.do" method="get" id="downloadForm" name="downloadForm" target="_self"> </form> click: { fn: function() { document.getElementById('downloadForm').submit(); } } 
0
source

To make it work with ExtJS 3.4:

  var hiddenForm = new Ext.FormPanel({ id:'hiddenForm', region: 'south', method: 'POST', url: "/cgi/test.wsgi", height: 0, standardSubmit: true, hidden:true, items:[ {xtype:'hidden', name:'p', value:p}, {xtype:'hidden', name:'g', value:g}, // ... ], }); linkThis = new Ext.Button({ text: 'Download this CSV', handler: function() { hiddenForm.getForm().submit(); }, maxHeight: 30, }); 

Remember that in order to make it work, you must place hiddenForm in any container (i.e. in the same Ext.Window button), for example:

  risultatiWindow = new Ext.Window({ title: 'CSV Export', height: 400, width: 500, .... items: [...., hiddenForm] }); 
0
source

All Articles