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;
|
---|