Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide (in IE and Firefox) a binary file download in a popup that closes?

I need a cross-browser solution to the following use case: The user clicks an "export" button on one of our pages, which opens a popup with a form. On submitting the form, the user should receive a binary file download (a CSV file, for example), and the popup should close without changing the visible content of the parent window.

We can't use a timeout to close the popup, because there's typically a dialog asking the user how to handle the file before downloading it, and there's no way of knowing how long it will take the user to handle this dialog.

We originally had a script in the popup which sets window.location to the download file URL. That leaves the popup unclosed.

So then I tried putting a hidden iFrame in the parent window and having the popup set the iFrame's src to the download URL before calling self.close(). That works perfectly in Firefox, but IE completely mangles it with security restrictions.

Is there a right way to do this ? How about a way that works on IE ?


Update - problem solved

The answers proposed here were not too far off, but my problem was a bit more complex than just being a Javascript issue. I encountered bugs with IE and Excel (since the download file is CSV), and the popup was doing a form post.

I could not solve the problem without appending the form data to a URL (for a GET instead of a POST), and I have to set the site as trusted in IE (this is an enterprise app, so that's a reasonable request to make of the users).

On the click of the form button, the popup calls a function on window.opener, passing in the form and its action URL. Then the popup calls window.close(). The function appends the form data to the URL and sets window.location to the new URL (the iFrame idea never worked well in IE and apparently was not necessary).

In the response to the form URL, the request headers include Content-Type: application/octetstream and Content-Disposition", "attachment; filename=filename.csv".

like image 785
aro_biz Avatar asked Nov 25 '22 22:11

aro_biz


1 Answers

Have you tried, in the iframe solution, to actually call a method inside the parent window, which in turn will set the location of the iframe? I'm asking because it worked in my tests:

Parent Window

<html>
<head>
<script type="text/javascript">
var w;

var download = function() {
    document.frames[0].location = "test.php";
    w.close();
};

var o = function() {
    w = window.open("test2.html", "window_name");
    return false;
};
</script>
</head>
<body>

<a href="#" onclick="return o();">open</a>

<iframe></iframe>

</body>
</html>

Popup window

<html>
<head>
<script type="text/javascript">
var download = function() {
    window.opener.download();
    return false;
};
</script>
</head>
<body>

<a href="#" onclick="return download();">download</a>

</body>
</html>

test.php is just a page that forces a file for download, and please note that the above code is IE specific as I'm using the document.frames object, but it can be easily made cross-browser.

like image 106
Ionuț G. Stan Avatar answered Dec 15 '22 05:12

Ionuț G. Stan