Reputation: 7647
I have a situation where i need to download a excel file. So i user Window.open for that. The problem is i need to check whether the file is exsist in the server location before call the Window.open. So when user click the download buton below call happens,
public void onClick(Button button, EventObject e) {
final String url = GWT.getModuleBaseURL() + "fileupload/dailyLogReport?param1=param1
openFileDownloadWindow(url,fileName);
}
public void openFileDownloadWindow(final String url,String fileName){
CommonServiceAsync serviceAsyn = CommonService.Util.getInstance();
final AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result)
{
isFileExsist = (Boolean)result;
if(isFileExsist){
Window.open( url, "_blank", "status=0,toolbar=0,menubar=0,location=0");
}else{
Window.alert("File not found.");
}
}
public void onFailure(Throwable caught)
{
MessageBox.alert("Error", "Error while getting data"
+ caught.getMessage());
}
};
// calling of the action
serviceAsyn.isDailyLogFileExsists(fileName, callback);
}
But the problem is if i put the Window.open inside the success it just open a Window and getting it close quickly with out download the file. But if i put the Window.open directly in onClick method it successfully open the window pop up and download the file successfully. But Since i have to download the file conditionally by checking whether the file is exists or not I can not put the Window.open inside onClick.
What is the reason Window.open not working properly inside the call back success function?
Upvotes: 1
Views: 2190
Reputation: 9741
The problem is popup blocker.
When you click on a element you can open a new window since the browser considers it is a deliberate user action to open the window.
Otherwise, the browser blocks any window.open in asynchronous blocks, because it considers that it could be malicious code run out of the user control.
The best solution, is to open the file in an iframe, but you have to set the appropriate content-disposition header in server side which causes the browser to show the "Save" dialog.
Client Code:
// Create a new iframe
final Frame f = new Frame();
f.setUrl(url_to_my_excel_file");
// Set a size of 0px unless you want the file be displayed in it
// For .html images .pdf, etc. you must configure your servlet
// to send the Content-Disposition header
f.setSize("0px", "0px");
RootPanel.get().add(f);
// Configure a timer to remove the element from the DOM
new Timer() {
public void run() {
f.removeFromParent();
}
}.schedule(10000);
Server Code:
protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException {
[...]
// Set the appropriate type for your file
resp.setContentType("application/vnd.ms-excel");
// Mandatory if you want the browser open the save dialog
resp.setHeader("Content-Disposition:", "attachment;filename='my_excel_file.xls'");
[...]
}
Upvotes: 1