IE iframe download causing security warning - javascript

My application takes AJAX requests and responds with a URL to a download location on my website for the file they're requesting. Then the Javascript AJAX method for success of the response, dynamically creates an iframe on the page with the src set to the download location, to allow the file dialog to display so the user can download the file. The problem is IE displays the following security warning:
http://avnhelp.com/default_files/image004.jpg
The main reason this is a problem is because, when they click accept, it refreshes the page and the file download is lost (I'm assuming this is because it's in an iframe created dynamically).
I need a way to either:
disable this security dialog prompt
prompt the user when they visit the
site to accept any future file
downloads.
fix the fact that upon refresh (from
accepting) the file download is lost.
Here is my iframe code:
function create_iframe(url) {
frame = document.createElement('IFRAME');
frame.setAttribute('src', url);
frame.style.display = 'none';
document.body.appendChild(frame);
}
If someone could help me with this, that'd be great! Thanks.

You can't disable the security warning. The browser will act like that whenever a file attachment shows up in an HTTP response that's not related to an HTTP request made from a user-initiated event ("click" or form submit). You're getting the warning because you're making the HTTP request from the ajax response event handler, and the browser simply does not like that.
The only way to make the setup work is to make sure that you start the HTTP request from a "click" handler, or the "submit" handler for a form (or by having the actual form submit result in the file response).

Related

Detecting iframe load when downloading a file through the iframe

I'm using AngularJS and setting ngSrc on an iframe, which I use to download a zipped archive to get around not being able to download files using AJAX. I'm using a directive for detecting the iframe load that I found here, which works great when you load a URL like "about:blank", but it doesn't have a load when I hit it with a RESTful call to download the file, even though it downloads the generated file.
// Markup of iframe using ngSrc and custom directive
<iframe ng-src="{{url}}" style="display:none;" iframe-onload="myCallback" />
// Controller setting iFrame, what I'd like to trigger the load
$scope.downloadArchive = function( id ) { // no load event? but downloads zip archive
var url = '/data/archive/instance/' + id;
$scope.url = $sce.trustAsResourceUrl( url );
}
// Controller setting iFrame, what does trigger the load
$scope.downloadArchive = function( id ) { // load event triggered
$scope.url = $sce.trustAsResourceUrl('about:blank');
}
Is is possible to detect an event when downloading a zipped archive through the iframe?
Is it that you can't download the file via AJAX due to browser restrictions? Like cross domain issues? You can find out by examining the error in Chrome Console.
If that is the case, you won't be able to view the contents of the file in an iframe either due to modern browser restrictions. Think of what can happen if developers are allowed to access the contents of any iframe. I could make a website with your bank's website in an iframe. Once you log in, I'd be able to listen to a form submit event from the iframe and then get your login credentials.
Hence, what could be happening is that your iframe is loading the file, trying to display the file within it, but intentionally hindering you from viewing its contents for security.
I'd recommend downloading the file via a proxy server you own or through a cloud service, and then serving the file from your own server. This circumvents cross domain issues since you can now ping your own server.
I ended up not trying to reset the URL each time and just appended the current time as a second parameter, which gets ignored by the server. Now it appears like iframe is reloading a new URL.
var url = '/data/archive/instance/' + id + '/' + Date.now();

How do I execute some javascript after a file is downloaded?

I have a page with a link to a file. When the link is clicked I use the code below to show a loading message:
$('#TerritoriesToExcelLink').click(function() {
$('#TerritoriesToExcelLoading').show();
window.location.href = $(this).attr('href');
});
I'd like to hide the message once the file is downloaded and the save dialog pops up in the browser.
I've tried adding some code that fires on ready() but that seems to just run straight away (presumably since the page is already loaded even if the file isn't) so the loading message never gets displayed.
How can I hide the loading message once the file has been completely downloaded?
Have your server send a random cookie that you specify from your client-side code with your download in the HTTP headers. Poll in your Javascript to check for the presence of the cookie. This should tell you when the browser has your file.
If you aren't opposed to using flash...
You could create an invisible flash object on the page, then when you click the download link, you could trigger flash to download the file, then handle the flash download complete event and use the ExternalInterface API to raise the event in javascript.
This is not possible to do with front end javascript, there is no way for it to retrieve the progress of a download and it doesn't have any events relating to downloads.
I don't think tracking the progress can be done with server side languages either.

How does a javascript download link work?

I've been using the Microsoft Technet site and you can download the ISO files by clicking a link on the page. The element is like this:
<a href="javascript:void(0)" onmouseout="HideToolTip()"
onmouseover="ShowToolTip(event,'Click here to download.')"
onclick="javascript:RunDownload('39010^313^164',event)"
class="detailsLink">Download</a>
I wasn't able to find the RunDownload() method in the scripts. And I wondered what it is likely to do. I mean usually when I provide a link for someone to download I provide an anchor to it:
download
But this is working differently what is the script doing? Because even when I ran 'Fiddler' I wasn't able to see the actual download location.
there's no such thing as a "javascript download" link. Javascript can open a new window, or simulate a click on a link.
What you have to find is which url the function triggered by this click will lead to.
here's an example of how to do it:
Suppose we have a:
<a id="download">download Here ยงยงยง</a>
then this jQuery code:
$('#download').click( function() {
window.location.href = 'http://example.org/download/ISO.ISO';
} );
will redirect to the URL http://example.org/download/ISO.ISO. Whether this url starts a download or not depends on HTTP headers and your browser, not on what javascript do.
Download location can be a url-rewritten path. This mean that maybe some parameters are given with HTTP Post and some HTTP handler in the Web server or web application may be getting some arguments from the HTTP request and write file bytes to an HTTP response, which absolutely hides where the file is located in the actual server's file system.
Maybe this is what's behind the scenes and prevents you to know the file location.
For example, we can have this:
http://mypage.com/downloads/1223893893
And you requested an executable like "whatever.exe" for downloading it to your hard disk. Where's the "http:/mypage.com/downloads/whatever.exe"? Actually, it doesn't exist. It's a byte array saved in a long database in some record, and "mypage" web application handles a request for a file that's identified as "1223893893" which can be a combination of an identifier, date time or whichever argument.
What I think the function RunDownload might do is that it might inform the server using get request to the server that another download is about to happen , or it might need to run the download background by setting the target attribute to an iframe so the user won't need to open another tab and download the file on the same page.
Download
JS
var runDownload=function(){
e.preventDefault();
increaseDownloadCountOnTheServer(location);
window.location.href="filelocation.exe";
}

Initiating a download with javascript

I need to dynamically initiate a download with javascript. I have seen how people do this by doing something like
window.open("some url", "Download");
but I need to do it without changing the url of the current page (and not using frames if I can help it, or created and destroying a frame dynamically). Anybody know how to do this?
You don't need window.open(). It's plain ugly and prone to popupblockers (where you have no control over in clients). Just window.location is sufficient if the response header of the requested download URL contains Content-Disposition: attachment. This won't change the current URL in the browser address bar nor the current page, but just pop a Save As dialogue.
E.g.
window.location = 'http://download.winzip.com/winzip145.exe';

Using Javascript to send an HTTP attachment to the user (open browser's Save as... dialog)

I'm new to web development, so I apologize if this question is noobish. I want to serve a file that is on the server's hard drive to the user when requested (ie, send an HTTP attachment to trigger the browser's "Save as..." dialog) in Javascript. The user clicks on a button on the page, the server generates a customized data file based on some of his/her account settings (and other parameters), and then the "Save as..." dialog should pop up. How should I go about implementing this in Javascript?
edit: for your reference, the server has Glassfish and Apache
Jane,
The save-as dialog only appears on page load. You need to redirect your user either directly to the file you want them to save, or to a server-side page that serves up the file.
Once you know the address of the file, do something like
window.location = http://yourserver.com/generatedfiles/file_2342342.txt
Alternatively, do something like this:
window.location = http://yourserver.com/getgeneratedfile.aspx?fileID=2342342
...which would redirect the user to a page that feeds the generated file. You then need to specify the content-disposition and filename in the header that comes from that page, as mentioned in Gandalf's reply.
Edit: Ah, you're using Apache. Probably won't have ASPX files on there then.
Set the Http Response header:
Content-Disposition: attachment; filename=myfile.txt
Or something like this
Save this page
#aric's answer is correct; however, window.location will cause load/unload events to get fired which may not be desirable for your application. In this case, you can likely direct a hidden iframe to the url to cause the save dialog to appear without losing your page's state.
Also, 'SaveAs' is probably an IE specific value for document.execCommand as it doesn't exist in Firefox.

Categories