UNPKG

2.29 kBJavaScriptView Raw
1/**
2 * Generic Transport for the browser, using the XmlHttpRequest object
3 *
4 * @class connections.Xhr
5 */
6module.exports = XhrConnector;
7
8/* eslint-env browser */
9
10var _ = require('lodash');
11var utils = require('../utils');
12var ConnectionAbstract = require('../connection');
13var ConnectionFault = require('../errors').ConnectionFault;
14var asyncDefault = !(navigator && /PhantomJS/i.test(navigator.userAgent));
15
16function XhrConnector(host, config) {
17 ConnectionAbstract.call(this, host, config);
18}
19utils.inherits(XhrConnector, ConnectionAbstract);
20
21/**
22 * Simply returns an XHR object cross browser
23 * @type {Function}
24 */
25var getXhr = _.noop;
26
27if (typeof XMLHttpRequest !== 'undefined') {
28 // rewrite the getXhr method to always return the native implementation
29 getXhr = function() {
30 return new XMLHttpRequest();
31 };
32} else {
33 // find the first MS implementation available
34 getXhr = _(['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'])
35 .map(function(appName) {
36 try {
37 var test = new window.ActiveXObject(appName); // eslint-disable-line no-unused-vars
38 return function() {
39 return new window.ActiveXObject(appName);
40 };
41 } catch (e) {
42 return false;
43 }
44 })
45 .compact()
46 .head();
47}
48
49if (!getXhr) {
50 throw new Error('getXhr(): XMLHttpRequest not available');
51}
52
53XhrConnector.prototype.request = function(params, cb) {
54 var xhr = getXhr();
55 var timeoutId;
56 var host = this.host;
57 var log = this.log;
58
59 var url = host.makeUrl(params);
60 var headers = host.getHeaders(params.headers);
61 var async = params.async === false ? false : asyncDefault;
62
63 xhr.open(params.method || 'GET', url, async);
64
65 if (headers) {
66 for (var key in headers) {
67 if (headers[key] !== void 0) {
68 xhr.setRequestHeader(key, headers[key]);
69 }
70 }
71 }
72
73 xhr.onreadystatechange = function() {
74 if (xhr.readyState === 4) {
75 clearTimeout(timeoutId);
76 log.trace(params.method, url, params.body, xhr.responseText, xhr.status);
77 var err = xhr.status
78 ? void 0
79 : new ConnectionFault(xhr.statusText || 'Request failed to complete.');
80 cb(err, xhr.responseText, xhr.status);
81 }
82 };
83
84 xhr.send(params.body || void 0);
85
86 return function() {
87 xhr.abort();
88 };
89};