100 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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'));
 | 
						|
  };
 | 
						|
};
 |