'use strict';
|
|
|
|
var random = require('../../utils/random')
|
|
, urlUtils = require('../../utils/url')
|
|
;
|
|
|
|
var debug = function() {};
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
debug = require('debug')('sockjs-client:sender:jsonp');
|
|
}
|
|
|
|
var form, area;
|
|
|
|
function createIframe(id) {
|
|
debug('createIframe', id);
|
|
try {
|
|
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
|
|
return global.document.createElement('<iframe name="' + id + '">');
|
|
} catch (x) {
|
|
var iframe = global.document.createElement('iframe');
|
|
iframe.name = id;
|
|
return iframe;
|
|
}
|
|
}
|
|
|
|
function createForm() {
|
|
debug('createForm');
|
|
form = global.document.createElement('form');
|
|
form.style.display = 'none';
|
|
form.style.position = 'absolute';
|
|
form.method = 'POST';
|
|
form.enctype = 'application/x-www-form-urlencoded';
|
|
form.acceptCharset = 'UTF-8';
|
|
|
|
area = global.document.createElement('textarea');
|
|
area.name = 'd';
|
|
form.appendChild(area);
|
|
|
|
global.document.body.appendChild(form);
|
|
}
|
|
|
|
module.exports = function(url, payload, callback) {
|
|
debug(url, payload);
|
|
if (!form) {
|
|
createForm();
|
|
}
|
|
var id = 'a' + random.string(8);
|
|
form.target = id;
|
|
form.action = urlUtils.addQuery(urlUtils.addPath(url, '/jsonp_send'), 'i=' + id);
|
|
|
|
var iframe = createIframe(id);
|
|
iframe.id = id;
|
|
iframe.style.display = 'none';
|
|
form.appendChild(iframe);
|
|
|
|
try {
|
|
area.value = payload;
|
|
} catch (e) {
|
|
// seriously broken browsers get here
|
|
}
|
|
form.submit();
|
|
|
|
var completed = function(err) {
|
|
debug('completed', id, err);
|
|
if (!iframe.onerror) {
|
|
return;
|
|
}
|
|
iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
|
|
// Opera mini doesn't like if we GC iframe
|
|
// immediately, thus this timeout.
|
|
setTimeout(function() {
|
|
debug('cleaning up', id);
|
|
iframe.parentNode.removeChild(iframe);
|
|
iframe = null;
|
|
}, 500);
|
|
area.value = '';
|
|
// It is not possible to detect if the iframe succeeded or
|
|
// failed to submit our form.
|
|
callback(err);
|
|
};
|
|
iframe.onerror = function() {
|
|
debug('onerror', id);
|
|
completed();
|
|
};
|
|
iframe.onload = function() {
|
|
debug('onload', id);
|
|
completed();
|
|
};
|
|
iframe.onreadystatechange = function(e) {
|
|
debug('onreadystatechange', id, iframe.readyState, e);
|
|
if (iframe.readyState === 'complete') {
|
|
completed();
|
|
}
|
|
};
|
|
return function() {
|
|
debug('aborted', id);
|
|
completed(new Error('Aborted'));
|
|
};
|
|
};
|