IE9 prompts user on submission of hidden iFrame

2019-02-16 18:25发布

问题:

I am debugging our file uploading script, which uses a hidden iframe in browsers that do not support sending file data via an XMLHttpRequest object.

There is a plethora of articles and questions on submitting an iframe in IE; (like this post, and this post), but they all cite the fact that IE will not properly set the 'name' attribute for you.

The code below produces a form whose target is set to the name of the iFrame, but on submitting the form, IE9 still prompts me with "Do you want to open or save photo_upload.json?", instead of loading it into the iFrame.

var $iframe = $("<iframe id='" + id + "' name='" + id + "' />");
$('body').append($iframe);

$iframe.load(function () {
  console.log("loaded");  // this never happens in IE9
});

// pretend this form also has a file input object that gets populated
var $form = $('<form />').attr({
  method: "post",
  enctype: "multipart/form-data",
  action: "/photo_upload.json",
  target: id
});

$('body').append($form);
$form.submit();  

This code works in FF and Chrome, but in IE9 I get prompted to open or save 'photo_upload.json'. The response that IE9 gets is accurate, if I open the file.

Does anyone have any insight? Is there anything I'm missing to get the iframe submission to go through? Do I need to set a header of some sort to tell IE not to open it like that? Thank you!

Solution:

Code that solved it for me, thanks to @Kolink.

Rails server side code, in the photo_upload function:

if params[:from_iframe]
  render :json => @temp_photo, :content_type => "text/html"
else
  render :json => @temp_photo
end

I pass an extra parameter when the form is submitted from the iframe, so I can use the same server side function whether the photo upload is an AJAX request, or a hidden iFrame.

In the latter case, as @Kolink recommends, this will get the JSON out of the iFrame:

$iframe.load(function () {
  json_string = iframe[0].contentDocument.body.innerHTML;
});

回答1:

photo_upload.json IS being downloaded into the iframe, but because the browser doesn't know what to do with it, it assumes it to be a file for download.

Ideally, you should have the iframe receive HTML data, which may contain a <script> to tell the parent window what to do. Alternatively, if you already have code in the parent to handle receiving the response (which it looks like you do), set Content-Type: text/html on the response to force the browser to treat it as an HTML document - it will automatically add the basics like an <html> tag and a <body> tag, so just access iframe.contentDocument.body.innerHTML.