Created
January 10, 2014 14:48
-
-
Save corsonx/8355590 to your computer and use it in GitHub Desktop.
Posting a form via AJAX through a hidden iFrame. This is necessary when uploading an image using ajax for IE < 10. It is also useful in other cases, where your post endpoint cannot easily digest JSON, for instance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This particular code works with html that looks like this: | |
<div class="upload_container" id="photo_number_1"> | |
<div><input name="upload" class="photo_upload_field" type="file" /></div> | |
<div><input type="button" class="upload_photo_submit" value="Upload Photo"></div> | |
<p class="center loading hidden"><img src="/assets/loading.gif"></p> | |
<script> | |
// yes, I know, don't actually put this in a script tag here. It's for illustration purposes only | |
$('.upload_photo_submit')[0]).click(function(event){ajaxFileUpload(event);}); | |
</script> | |
</div> | |
// This can of course be made generic to apply to many different inputs, but I'm lazy. | |
// This just goes in your JS files. | |
var ajaxFileUpload = function(event){ | |
var p_container = $(event.target).closest('.upload_container'); | |
var upload_field = $(p_container.find('.photo_upload_field')).first(); | |
if ((upload_field.val() == '') == true) { | |
alert('Please select a file to upload.'); | |
} else { | |
p_container.find(".loading").removeClass('hidden'); | |
if (isAjaxUploadSupported()) { | |
var fData = new FormData(); | |
fData.append('upload',upload_field[0].files[0]); | |
$.ajax({ | |
url:'/photo/upload', | |
enctype: 'multipart/form-data', | |
type: 'POST', | |
data: fData, | |
processData: false, | |
contentType: false, | |
cache: false, | |
success: function (data, status) { | |
addClassifiedPhoto(data, p_container); | |
}, | |
error: function (data, status, e) { | |
alert(JSON.stringify(data['responseJSON'])); | |
}, | |
complete: function() { | |
p_container.find(".loading").addClass('hidden'); | |
} | |
}) | |
} else { // IE fallback | |
var iframe = document.createElement("iframe"); | |
iframe.setAttribute("name", "upload_iframe_myFile"); | |
iframe.setAttribute("id", "upload_iframe_myFile"); | |
iframe.setAttribute("width", "0"); | |
iframe.setAttribute("height", "0"); | |
iframe.setAttribute("border", "0"); | |
iframe.setAttribute("src","javascript:false;"); | |
iframe.style.display = "none"; | |
var form = document.createElement("form"); | |
form.setAttribute("target", "upload_iframe_myFile"); | |
form.setAttribute("action", "/photo/upload/?ctype=text%2Fhtml"); | |
form.setAttribute("method", "post"); | |
form.setAttribute("enctype", "multipart/form-data"); | |
form.setAttribute("encoding", "multipart/form-data"); | |
form.style.display = "none"; | |
form.appendChild(upload_field[0]); | |
document.body.appendChild(form); | |
document.body.appendChild(iframe); | |
iframeIdmyFile = document.getElementById("upload_iframe_myFile"); | |
// Add event... | |
var eventHandlermyFile = function() { | |
if (iframeIdmyFile.detachEvent) { | |
iframeIdmyFile.detachEvent("onload", eventHandlermyFile); | |
} else { | |
iframeIdmyFile.removeEventListener("load", eventHandlermyFile, false); | |
} | |
response = getIframeContentJSON(iframeIdmyFile); | |
if (response.success == 'false') { | |
alert('Failed to upload'); | |
p_container.find(".loading").addClass('hidden'); | |
} else { | |
addClassifiedPhoto(response, p_container); | |
p_container.find(".loading").addClass('hidden'); | |
} | |
} | |
if (iframeIdmyFile.addEventListener){ iframeIdmyFile.addEventListener("load", eventHandlermyFile, true);} | |
if (iframeIdmyFile.attachEvent) { iframeIdmyFile.attachEvent("onload", eventHandlermyFile);} | |
form.submit(); | |
} | |
} | |
} | |
function isAjaxUploadSupported(){ | |
var input = document.createElement("input"); | |
input.type = "file"; | |
return ( | |
"multiple" in input && typeof File != "undefined" && typeof FormData != "undefined" && | |
typeof (new XMLHttpRequest()).upload != "undefined" ); | |
} | |
function getIframeContentJSON(iframe){ | |
//IE may throw an "access is denied" error when attempting to access contentDocument on the iframe in some cases | |
try { | |
// iframe.contentWindow.document - for IE<7 | |
var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document, response; | |
var innerHTML = doc.body.innerHTML; | |
//plain text response may be wrapped in <pre> tag | |
if (innerHTML.slice(0, 5).toLowerCase() == "<pre>" && innerHTML.slice(-6).toLowerCase() == "</pre>") { | |
innerHTML = doc.body.firstChild.firstChild.nodeValue; | |
} | |
response = eval("(" + innerHTML + ")"); | |
} | |
catch(err){ | |
response = {success: false}; | |
} | |
return response; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
//IE may throw an "access is denied" error when attempting to access contentDocument on the iframe in some cases
Maybe is when x-frame-options is set to deny?