Instantly share code, notes, and snippets.
Last active
August 8, 2018 03:06
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save thanpolas/723d0ec4ac418841eec0 to your computer and use it in GitHub Desktop.
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).
This file contains 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
/** | |
* @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