Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
In the absence of CORS support the Hidden Iframe technique is the only way to submit a big amount of data (over 2kb that jsonp can handle).
/**
* @fileOverview Hidden iFrame implementation for browsers without CORS.
*
* Usage:
* var iframe = new Iframe();
* iframe.submit(url, {data: yourData}, function(err) {});
*
* The server will get a POST request on the defined URL with the data
* JSON encoded in the body attribute named "data".
*/
var noop = function() {};
/**
* Hidden iFrame implementation for browsers without CORS.
*
* @constructor
*/
var Iframe = module.exports = function() {
/** @type {String} The target action of the form submission */
this.url = '';
/** @type {Object} Contains the invoke options */
this.opts = {};
/** @type {Function} User defined callback */
this.cb = noop;
/** @type {?Document.iframe} iframe document instance */
this.iframe = null;
/** @type {?Document.form} form document instance */
this.form = null;
/** @type {String} The name / id of the iframe */
this.iframeName = 'hidden_iframe_submit';
/** @type {?Document.iframe} The iframe element on the DOM */
this.iframeEl = null;
this._iframeLoadBinded = this._onIframeLoad.bind(this);
};
/**
* Submit data using a hidden iframe.
*
* @param {string} url The url to submit to.
* @param {Object} opts Options for the submission.
* @param {*} data Data to send.
* @param {Function} cb Nodejs Callback.
*/
Iframe.prototype.submit = function(url, opts, cb) {
this.url = url;
this.cb = cb;
this.opts = opts;
this._createIframe();
this._createForm();
document.body.appendChild(this.form);
document.body.appendChild(this.iframe);
this.iframeEl = document.getElementById(this.iframeName);
if (this.iframeEl.addEventListener) {
this.iframeEl.addEventListener('load', this._iframeLoadBinded, true);
}
if (this.iframeEl.attachEvent) {
this.iframeEl.attachEvent('onload', this._iframeLoadBinded);
}
this.form.submit();
};
/**
* Triggers when iframe emits the onload event.
*
* @private
*/
Iframe.prototype._onIframeLoad = function() {
// Add event...
if (this.iframeEl.detachEvent) {
this.iframeEl.detachEvent('onload', this._iframeLoadBinded);
} else {
this.iframeEl.removeEventListener('load', this._iframeLoadBinded, false);
}
this.cb(null);
};
/**
* Create the iframe object.
*
* @private
*/
Iframe.prototype._createIframe = function() {
var iframe = this.iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.setAttribute('name', this.iframeName);
iframe.setAttribute('id', this.iframeName);
iframe.setAttribute('width', '0');
iframe.setAttribute('height', '0');
iframe.setAttribute('border', '0');
iframe.setAttribute('src', 'javascript:false;');
};
/**
* Create the form to submit.
*
* @private
*/
Iframe.prototype._createForm = function() {
var form = this.form = document.createElement('form');
form.style.display = 'none';
form.setAttribute('target', this.iframeName);
form.setAttribute('action', this.url);
form.setAttribute('method', 'post');
form.setAttribute('enctype', 'application/x-www-form-urlencoded');
form.setAttribute('encoding', 'application/x-www-form-urlencoded');
var input = document.createElement('input');
input.style.display = 'none';
input.setAttribute('type', 'text');
input.setAttribute('name', 'data');
var data = this._jsonData();
input.setAttribute('value', data);
form.appendChild(input);
};
/**
* JSON Stringify the incoming data.
*
* @return {string} JSON Encoded string.
* @private
*/
Iframe.prototype._jsonData = function() {
var data = {};
try {
data = JSON.stringify(this.opts.data);
} catch(ex) {
// no action
}
return data;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment