39

I'm trying to submit a form with a file field in it via jQuery.Form plugin, here's the code:

$('form').ajaxSubmit({
  url: "/path",
  dataType: "json",
  contentType: "multipart/form-data"
...

The server then returns json as a response. Works great in all browsers except IE, which tries to download the response as a file. If I remove the file field from the form, it also works just fine.

I've seen various solutions here and in Google and basically tried almost everything described, including setting enctype for the form via jQuery, but it didn't work.

Any suggestions would be very welcomed.

T J
  • 42,762
  • 13
  • 83
  • 138
orion3
  • 9,797
  • 14
  • 67
  • 93
  • Seems like your page is redirecting. Can you post more of your solution, please? – karim79 Nov 16 '11 at 11:51
  • It's not redirecting. My Rails controller renders json (when I save that file in IE - I see exactly what should be in the returned json). – orion3 Nov 16 '11 at 12:04
  • 3
    Had the exact same problem and returning a "text/plain" content type seems to work. $.parseJSON works as well in Chrome, but in IE
     tags are added. After replacing the 
     tags it all works fine.
    –  Jan 12 '12 at 16:19

9 Answers9

21

You can simply return JSON from the controller as "text/html" and then parse it on the client side using JQuery.parseJSON().

Controller:

    return this.Json(
            new
                {
                    prop1 = 5,
                    prop2 = 10
                }, 
            "text/html");

Client side:

jsonResponse = $.parseJSON(response);

if(jsonResponse.prop1==5) {
     ...
}

This solution has been working for me.

Dmitrii
  • 1,247
  • 4
  • 14
  • 28
  • 2
    This worked for me as well, but it seems ridiculous that I have to change this call on the service side for IE. – ymerej Oct 12 '12 at 23:50
  • 1
    Actually, only IE versions older then IE 10 are affected by this. If you want to make this workaround conditional (it might have performance implications), you can check the "Accept" request header. You only have to use this workaround if the "Accept" header doesn't contain "application/json". I solved this using a response filter for DRYness. – chris Sep 02 '13 at 13:36
  • +1 I was trying with Asp.Net MVC to return a ContentResult type with a json value and everything was working fine except with IE8. Now, using JsonResult with ContentType equals to 'text/html', it works in every browsers. – Samuel Apr 16 '15 at 16:54
10

I have not found a direct solution to this, but I eventually implemented the following workaround: I used dataType: "text" in my ajax settings and then returned plaintext from controller, separating values with ; and parsing them on the client side. That way IE and Forefox stopped trying to download a response.

I did not find any other way to prevent said behavior other then to return plaintext. I tried returning JSON as plaintext and then parsing it with $.parseJSON, but it didn't work due to some js errors.

orion3
  • 9,797
  • 14
  • 67
  • 93
  • 3
    Mine workaround was a bit different. I must set also header in a resposne to be a text/html. Because with `dataType: 'text'` ie8/ie9 it also want to download the file. – Max Małecki Nov 08 '12 at 13:47
  • 2
    Set your headers to text/plain for IE 8/9 and keep your dataType:'json'. IE 8/9 won't freak out and jquery will parse your data correctly in these cases. – zmonteca Dec 02 '13 at 22:49
6

Just send response with 'Content-Type', 'text/html' header.

T J
  • 42,762
  • 13
  • 83
  • 138
Sannek8552
  • 123
  • 1
  • 3
2

Just set Content-Type: text/html

This happens because IE8 doesn't recognize application/... mimetype. This works for me.

Hope it helps.

2

Same situation than you folks : the problem only occurs with enctype="multipart/form-data" form used with $(form).ajaxSubmit(...) function.

My team and I had to replace (in this function) dataType: 'json' option with dataType: 'text' and add responseText = $.parseJSON(responseText); to force server response parsing.

Of course we also had to step in server side to return a response with "text/plain" header instead of "application/json"

We're not proud of it :( IE is definitely killing everything...

I didn't try the advice given by zmonteca (already spent too much time on it) but it seems worthy : let us know if it was OK for you.

Hope it helps!

T J
  • 42,762
  • 13
  • 83
  • 138
lboix
  • 969
  • 12
  • 14
1

if you work with Zend you can do

$this->getResponse()->setHeader('Content-Type', 'text/html');

in your controller action. and on client-side, in case of jQuery, you can do

data = $.parseJSON(data);
Vanya
  • 11
  • 1
0

This site has some info about wrapping the response in a http://forum.jquery.com/topic/jquery-form-malsup-ie7-file-download-security-warning-on-ajax-file-upload

I seemed to be able to fix my problem by making my server return the JSON as a string. Then I used JSON.parse() inside the complete event.

keza
  • 2,601
  • 2
  • 16
  • 10
0

I came up with the following workaround (in Zend Framework):

if (!$this->_request->isXmlHttpRequest()) {
    die('<textarea>'.Zend_Json::encode($data).'</textarea>');
}
$this->view->assign($data);
sroes
  • 14,663
  • 1
  • 53
  • 72
-2

Removing ContentType from serverside works for me.

bfncs
  • 10,007
  • 4
  • 32
  • 52
Neha
  • 1