Skip to content

Instantly share code, notes, and snippets.

@akaramires
Forked from corsonx/upload_via_iframe
Created January 19, 2017 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save akaramires/13f57c8f4638cbabf0b6947522bc4f76 to your computer and use it in GitHub Desktop.
Save akaramires/13f57c8f4638cbabf0b6947522bc4f76 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 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