Tuesday, December 2, 2008

IE File Download - Security Warning

File Download - Security Warning
Do you want to save this file, or find a program online to open it....

Have you ever seen this error when making an ajax request in IE? In particular this seems to happen when using the remote_form_for or remote_form_tag helper and try submitting the form via javascript. The expected result would be that the form would be submitted via ajax and then a RJS file would execute some Javascript on the client's page. Instead we get a stupid IE download popup.

This one always comes back to bite me when I add a new features to a site and I've been blissfully programming away in FF neglecting the red headed stepchild IE. Then comes the head scratching followed by some screaming when Google fails to return any sort of valuable search results on this subject. I am going to post the issue and resolution for myself and hopefully it will help some other people out there.

Here is an example of the HTML generated from remote_form_for.

<form method="post" id="user_form" action="/users"
onsubmit="new Ajax.Request('/users', {
asynchronous:true,
evalScripts:true,
parameters:Form.serialize(this)});
return false;"></form>

And here is some javascript function that would submit that form.

$('user_form').submit();

First off when you submit this form in IE it seems that it sends out an ajax request because the full page does not reload. As it turns out when you call $('user_form').submit() in IE it never calls the onsubmit handler so it never has a chance to return false and prevent a full page submission. Since the form is not submitted via ajax IE thinks you want to download the response, ie the RJS file, hence the popup. What makes this even more tricky is that the RJS you wanted to execute actually gets executed so it looks like it was an actual ajax submission but it in fact was not.

The simple solution is when you are trying to submit a remote form via javascript you should explicitly call the onsubmit handler like this.

$('user_form').onsubmit();

Doing it this way ensures that you are submitting the form via ajax and behavior will be consistent across all browsers.

"Im a PC and I handle form submissions differently"

2 comments:

mrflip said...

Thanks for this post, it didn't solve my problem but it led me to thinking about why it wasn't.

In my case I've found out that IE doesn't set the accept headers correctly, so you have to request a file with the right extension (.js, probably).

If you're not using one of the ruby remote form doodads, you'll want to not only set jQuery to munge the xhr headers, but also ensure the form is sent to /widget/69.js and not the default /widget/69

You can see the code snippet I use at http://gist.github.com/111459

cheers,
flip

Anonymous said...

After scratching my head for a couple of hours, wondering why a submit worked but an onchange didn't, I ran across your article. You're a lifesaver! Thanks for posting both the problem AND the solution. Cheers