| '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')); |
| }; |
| }; |