| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | 'use strict';// Few cool transports do work only for same-origin. In order to make// them work cross-domain we shall use iframe, served from the// remote domain. New browsers have capabilities to communicate with// cross domain iframe using postMessage(). In IE it was implemented// from IE 8+, but of course, IE got some details wrong://    http://msdn.microsoft.com/en-us/library/cc197015(v=VS.85).aspx//    http://stevesouders.com/misc/test-postmessage.phpvar inherits = require('inherits')  , EventEmitter = require('events').EventEmitter  , version = require('../version')  , urlUtils = require('../utils/url')  , iframeUtils = require('../utils/iframe')  , eventUtils = require('../utils/event')  , random = require('../utils/random')  ;var debug = function() {};if (process.env.NODE_ENV !== 'production') {  debug = require('debug')('sockjs-client:transport:iframe');}function IframeTransport(transport, transUrl, baseUrl) {  if (!IframeTransport.enabled()) {    throw new Error('Transport created when disabled');  }  EventEmitter.call(this);  var self = this;  this.origin = urlUtils.getOrigin(baseUrl);  this.baseUrl = baseUrl;  this.transUrl = transUrl;  this.transport = transport;  this.windowId = random.string(8);  var iframeUrl = urlUtils.addPath(baseUrl, '/iframe.html') + '#' + this.windowId;  debug(transport, transUrl, iframeUrl);  this.iframeObj = iframeUtils.createIframe(iframeUrl, function(r) {    debug('err callback');    self.emit('close', 1006, 'Unable to load an iframe (' + r + ')');    self.close();  });  this.onmessageCallback = this._message.bind(this);  eventUtils.attachEvent('message', this.onmessageCallback);}inherits(IframeTransport, EventEmitter);IframeTransport.prototype.close = function() {  debug('close');  this.removeAllListeners();  if (this.iframeObj) {    eventUtils.detachEvent('message', this.onmessageCallback);    try {      // When the iframe is not loaded, IE raises an exception      // on 'contentWindow'.      this.postMessage('c');    } catch (x) {      // intentionally empty    }    this.iframeObj.cleanup();    this.iframeObj = null;    this.onmessageCallback = this.iframeObj = null;  }};IframeTransport.prototype._message = function(e) {  debug('message', e.data);  if (!urlUtils.isOriginEqual(e.origin, this.origin)) {    debug('not same origin', e.origin, this.origin);    return;  }  var iframeMessage;  try {    iframeMessage = JSON.parse(e.data);  } catch (ignored) {    debug('bad json', e.data);    return;  }  if (iframeMessage.windowId !== this.windowId) {    debug('mismatched window id', iframeMessage.windowId, this.windowId);    return;  }  switch (iframeMessage.type) {  case 's':    this.iframeObj.loaded();    // window global dependency    this.postMessage('s', JSON.stringify([      version    , this.transport    , this.transUrl    , this.baseUrl    ]));    break;  case 't':    this.emit('message', iframeMessage.data);    break;  case 'c':    var cdata;    try {      cdata = JSON.parse(iframeMessage.data);    } catch (ignored) {      debug('bad json', iframeMessage.data);      return;    }    this.emit('close', cdata[0], cdata[1]);    this.close();    break;  }};IframeTransport.prototype.postMessage = function(type, data) {  debug('postMessage', type, data);  this.iframeObj.post(JSON.stringify({    windowId: this.windowId  , type: type  , data: data || ''  }), this.origin);};IframeTransport.prototype.send = function(message) {  debug('send', message);  this.postMessage('m', message);};IframeTransport.enabled = function() {  return iframeUtils.iframeEnabled;};IframeTransport.transportName = 'iframe';IframeTransport.roundTrips = 2;module.exports = IframeTransport;
 |