问题
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!
回答1:
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
}
}
回答2:
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
回答3:
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();
}
});
来源:https://stackoverflow.com/questions/29012888/extjs-5-download-file-from-post-servlet-request