-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathBaseService.js
More file actions
135 lines (107 loc) · 3.52 KB
/
BaseService.js
File metadata and controls
135 lines (107 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import React from 'react';
import utils from '../utils';
const validHttpStatuses = [200, 201, 202, 204]
var jsonContentEncoder = {
contentType: 'application/json; charset=utf-8',
encode: function (body) {
return JSON.stringify(body);
}
};
var formContentEncoder = {
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
encode: function (body) {
return utils.serializeFormObject(body);
}
};
function getContentEncoder(contentType) {
var encoder = jsonContentEncoder;
if (contentType && contentType.indexOf('application/x-www-form-urlencoded') === 0) {
encoder = formContentEncoder;
}
return encoder;
}
function makeHttpRequest(method, uri, body, headers, callback) {
var request = new XMLHttpRequest();
request.open(method.toUpperCase(), uri, true);
if (headers) {
for (var name in headers) {
// Skip the Content-Type header.
// This will be set later if we provided a body.
if (name === 'Content-Type') {
continue;
}
var value = headers[name];
request.setRequestHeader(name, value);
}
}
// If the URI is different than the URI of the domain we're on,
// then set withCredentials to true so that we enable CORS.
if (!utils.isRelativeUri(uri) && !utils.isSameHost(uri, window.location.href)) {
request.withCredentials = true;
}
request.onreadystatechange = function () {
// 4 = Request finished and response is ready.
// Ignore everything else.
if (request.readyState !== 4) {
return;
}
let result = {
status: request.status,
responseJSON: null
};
let caughtError = null;
try {
if (request.responseText) {
result.responseJSON = JSON.parse(request.responseText);
}
} catch(e) {
return callback(e);
}
callback(null, result);
};
if (body && typeof body === 'object') {
var contentEncoder = getContentEncoder(headers['Content-Type']);
request.setRequestHeader('Content-Type', contentEncoder.contentType);
request.send(contentEncoder.encode(body));
} else {
request.send();
}
}
export default class BaseService {
constructor(endpoints, forceAgentHeader) {
let defaultEndpoints = {
baseUri: null
};
this.endpoints = utils.mergeObjects(defaultEndpoints, endpoints);
this.forceAgentHeader = forceAgentHeader || false;
}
_makeRequest(method, path, body, headers, callback) {
var uri = this._buildEndpoint(path);
headers = headers || {};
if (!headers.Accept) {
headers.Accept = 'application/json';
}
// Only set the X-Stormpath-Agent header if we're on the same domain as the requested URI.
// This because we want to avoid CORS requests that require you to have to whitelist the X-Stormpath-Agent header.
if (this.forceAgentHeader || utils.isRelativeUri(uri) || utils.isSameHost(uri, window.location.href)) {
headers['X-Stormpath-Agent'] = `stormpath-sdk-react/${pkg.version} react/${React.version}`;
}
makeHttpRequest(method, uri, body, headers, function (err, result) {
if (err) {
return callback(err);
}
var data = result.responseJSON || {};
if (validHttpStatuses.indexOf(result.status) !== -1) {
callback(null, data);
} else {
var error = new Error(data.message || data.error || 'A request to the API failed.');
error.type = data.error;
error.status = result.status;
callback(error);
}
});
}
_buildEndpoint(endpoint) {
return (this.endpoints.baseUri || '') + endpoint;
}
}