-
Notifications
You must be signed in to change notification settings - Fork 1
/
AjaxRequest.js
137 lines (108 loc) · 3.88 KB
/
AjaxRequest.js
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
136
137
/* inspired by axios */
class AjaxRequest {
createError(message, code, request, response) {
var error = new Error(message);
if (code) {
error.code = code;
}
error.request = request;
error.response = response;
return error;
}
settle(resolve, reject, response) {
var validateStatus = function(status){
return status >= 200 && status < 300;
};
// Note: status is not exposed by XDomainRequest
if (!response.status || !validateStatus || validateStatus(response.status)) {
resolve(response);
} else {
reject(this.createError(
'Request failed with status code ' + response.status,
null,
response.request,
response
));
}
}
request(method, url, formData = null, configureFn = null){
return new Promise((resolve, reject)=> {
var request = new XMLHttpRequest();
var loadEvent = 'onreadystatechange';
request.open(method, url, true);
// Listen for ready state
request[loadEvent] = ()=> {
if (!request || request.readyState !== 4) {
return;
}
// The request errored out and we didn't get a response, this will be
// handled by onerror instead
// With one exception: request that using file: protocol, most browsers
// will return status as 0 even though it's a successful request
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
return;
}
// Prepare the response
var responseHeaders = request.getAllResponseHeaders();
var responseData = request.responseText;
var contentType = request.getResponseHeader('Content-Type');
if (contentType && contentType.indexOf('application/json') != -1) {
responseData = JSON.parse(responseData);
}
var response = {
data: responseData,
// IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201)
status: request.status === 1223 ? 204 : request.status,
statusText: request.status === 1223 ? 'No Content' : request.statusText,
headers: responseHeaders,
request: request
};
this.settle(resolve, reject, response);
// Clean up request
request = null;
};
// Handle browser request cancellation (as opposed to a manual cancellation)
request.onabort = ()=> {
if (!request) {
return;
}
reject(this.createError('Request aborted', 'ECONNABORTED', request));
// Clean up request
request = null;
};
// Handle low level network errors
request.onerror = ()=> {
// Real errors are hidden from us by the browser
// onerror should only fire if it's a network error
reject(this.createError('Network Error', null, request));
// Clean up request
request = null;
};
// Handle timeout
request.ontimeout = ()=> {
reject(this.createError('timeout exceeded', 'ECONNABORTED', request));
// Clean up request
request = null;
};
// // Handle progress if needed
// if (typeof config.onDownloadProgress === 'function') {
// request.addEventListener('progress', config.onDownloadProgress);
// }
// Not all browsers support upload events
// if (typeof progressCallback === 'function' && request.upload) {
// request.upload.addEventListener('progress', progressCallback);
// }
if (typeof configureFn === 'function') {
configureFn(request);
}
request.send(formData);
});
}
post(url, formData, configureFn = null){
return this.request('POST', url, formData, configureFn);
}
delete(url, formData, configureFn = null){
return this.request('DELETE', url, formData, configureFn);
}
}
export default new AjaxRequest();