[6a3a178] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | var EventEmitter = require('events').EventEmitter
|
---|
| 4 | , inherits = require('inherits')
|
---|
| 5 | , eventUtils = require('../../utils/event')
|
---|
| 6 | , browser = require('../../utils/browser')
|
---|
| 7 | , urlUtils = require('../../utils/url')
|
---|
| 8 | ;
|
---|
| 9 |
|
---|
| 10 | var debug = function() {};
|
---|
| 11 | if (process.env.NODE_ENV !== 'production') {
|
---|
| 12 | debug = require('debug')('sockjs-client:sender:xdr');
|
---|
| 13 | }
|
---|
| 14 |
|
---|
| 15 | // References:
|
---|
| 16 | // http://ajaxian.com/archives/100-line-ajax-wrapper
|
---|
| 17 | // http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx
|
---|
| 18 |
|
---|
| 19 | function XDRObject(method, url, payload) {
|
---|
| 20 | debug(method, url);
|
---|
| 21 | var self = this;
|
---|
| 22 | EventEmitter.call(this);
|
---|
| 23 |
|
---|
| 24 | setTimeout(function() {
|
---|
| 25 | self._start(method, url, payload);
|
---|
| 26 | }, 0);
|
---|
| 27 | }
|
---|
| 28 |
|
---|
| 29 | inherits(XDRObject, EventEmitter);
|
---|
| 30 |
|
---|
| 31 | XDRObject.prototype._start = function(method, url, payload) {
|
---|
| 32 | debug('_start');
|
---|
| 33 | var self = this;
|
---|
| 34 | var xdr = new global.XDomainRequest();
|
---|
| 35 | // IE caches even POSTs
|
---|
| 36 | url = urlUtils.addQuery(url, 't=' + (+new Date()));
|
---|
| 37 |
|
---|
| 38 | xdr.onerror = function() {
|
---|
| 39 | debug('onerror');
|
---|
| 40 | self._error();
|
---|
| 41 | };
|
---|
| 42 | xdr.ontimeout = function() {
|
---|
| 43 | debug('ontimeout');
|
---|
| 44 | self._error();
|
---|
| 45 | };
|
---|
| 46 | xdr.onprogress = function() {
|
---|
| 47 | debug('progress', xdr.responseText);
|
---|
| 48 | self.emit('chunk', 200, xdr.responseText);
|
---|
| 49 | };
|
---|
| 50 | xdr.onload = function() {
|
---|
| 51 | debug('load');
|
---|
| 52 | self.emit('finish', 200, xdr.responseText);
|
---|
| 53 | self._cleanup(false);
|
---|
| 54 | };
|
---|
| 55 | this.xdr = xdr;
|
---|
| 56 | this.unloadRef = eventUtils.unloadAdd(function() {
|
---|
| 57 | self._cleanup(true);
|
---|
| 58 | });
|
---|
| 59 | try {
|
---|
| 60 | // Fails with AccessDenied if port number is bogus
|
---|
| 61 | this.xdr.open(method, url);
|
---|
| 62 | if (this.timeout) {
|
---|
| 63 | this.xdr.timeout = this.timeout;
|
---|
| 64 | }
|
---|
| 65 | this.xdr.send(payload);
|
---|
| 66 | } catch (x) {
|
---|
| 67 | this._error();
|
---|
| 68 | }
|
---|
| 69 | };
|
---|
| 70 |
|
---|
| 71 | XDRObject.prototype._error = function() {
|
---|
| 72 | this.emit('finish', 0, '');
|
---|
| 73 | this._cleanup(false);
|
---|
| 74 | };
|
---|
| 75 |
|
---|
| 76 | XDRObject.prototype._cleanup = function(abort) {
|
---|
| 77 | debug('cleanup', abort);
|
---|
| 78 | if (!this.xdr) {
|
---|
| 79 | return;
|
---|
| 80 | }
|
---|
| 81 | this.removeAllListeners();
|
---|
| 82 | eventUtils.unloadDel(this.unloadRef);
|
---|
| 83 |
|
---|
| 84 | this.xdr.ontimeout = this.xdr.onerror = this.xdr.onprogress = this.xdr.onload = null;
|
---|
| 85 | if (abort) {
|
---|
| 86 | try {
|
---|
| 87 | this.xdr.abort();
|
---|
| 88 | } catch (x) {
|
---|
| 89 | // intentionally empty
|
---|
| 90 | }
|
---|
| 91 | }
|
---|
| 92 | this.unloadRef = this.xdr = null;
|
---|
| 93 | };
|
---|
| 94 |
|
---|
| 95 | XDRObject.prototype.close = function() {
|
---|
| 96 | debug('close');
|
---|
| 97 | this._cleanup(true);
|
---|
| 98 | };
|
---|
| 99 |
|
---|
| 100 | // IE 8/9 if the request target uses the same scheme - #79
|
---|
| 101 | XDRObject.enabled = !!(global.XDomainRequest && browser.hasDomain());
|
---|
| 102 |
|
---|
| 103 | module.exports = XDRObject;
|
---|