-
Notifications
You must be signed in to change notification settings - Fork 799
/
Request.js
249 lines (202 loc) · 7 KB
/
Request.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import { Util, DomUtil } from 'leaflet';
import { Support } from './Support';
var callbacks = 0;
function serialize (params) {
var data = '';
params.f = params.f || 'json';
for (var key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
var param = params[key];
var type = Object.prototype.toString.call(param);
var value;
if (data.length) {
data += '&';
}
if (type === '[object Array]') {
value = (Object.prototype.toString.call(param[0]) === '[object Object]') ? JSON.stringify(param) : param.join(',');
} else if (type === '[object Object]') {
value = JSON.stringify(param);
} else if (type === '[object Date]') {
value = param.valueOf();
} else {
value = param;
}
data += encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}
const APOSTROPHE_URL_ENCODE = '%27';
return data.replaceAll("'", APOSTROPHE_URL_ENCODE);
}
function createRequest (callback, context) {
var httpRequest = new window.XMLHttpRequest();
httpRequest.onerror = function (e) {
httpRequest.onreadystatechange = Util.falseFn;
callback.call(context, {
error: {
code: 500,
message: 'XMLHttpRequest error'
}
}, null);
};
httpRequest.onreadystatechange = function () {
var response;
var error;
if (httpRequest.readyState === 4) {
try {
response = JSON.parse(httpRequest.responseText);
} catch (e) {
response = null;
error = {
code: 500,
message: 'Could not parse response as JSON. This could also be caused by a CORS or XMLHttpRequest error.'
};
}
if (!error && response.error) {
error = response.error;
response = null;
}
httpRequest.onerror = Util.falseFn;
callback.call(context, error, response);
}
};
httpRequest.ontimeout = function () {
this.onerror();
};
return httpRequest;
}
function xmlHttpPost (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
httpRequest.open('POST', url);
if (typeof context !== 'undefined' && context !== null) {
if (typeof context.options !== 'undefined') {
httpRequest.timeout = context.options.timeout;
}
}
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
httpRequest.send(serialize(params));
return httpRequest;
}
function xmlHttpGet (url, params, callback, context) {
var httpRequest = createRequest(callback, context);
httpRequest.open('GET', url + '?' + serialize(params), true);
if (typeof context !== 'undefined' && context !== null) {
if (typeof context.options !== 'undefined') {
httpRequest.timeout = context.options.timeout;
if (context.options.withCredentials) {
httpRequest.withCredentials = true;
}
}
}
httpRequest.send(null);
return httpRequest;
}
// AJAX handlers for CORS (modern browsers) or JSONP (older browsers)
export function request (url, params, callback, context) {
var paramString = serialize(params);
var httpRequest = createRequest(callback, context);
var requestLength = (url + '?' + paramString).length;
// ie10/11 require the request be opened before a timeout is applied
if (requestLength <= 2000 && Support.cors) {
httpRequest.open('GET', url + '?' + paramString);
} else if (requestLength > 2000 && Support.cors) {
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
}
if (typeof context !== 'undefined' && context !== null) {
if (typeof context.options !== 'undefined') {
httpRequest.timeout = context.options.timeout;
if (context.options.withCredentials) {
httpRequest.withCredentials = true;
}
}
}
// request is less than 2000 characters and the browser supports CORS, make GET request with XMLHttpRequest
if (requestLength <= 2000 && Support.cors) {
httpRequest.send(null);
// request is more than 2000 characters and the browser supports CORS, make POST request with XMLHttpRequest
} else if (requestLength > 2000 && Support.cors) {
httpRequest.send(paramString);
// request is less than 2000 characters and the browser does not support CORS, make a JSONP request
} else if (requestLength <= 2000 && !Support.cors) {
return jsonp(url, params, callback, context);
// request is longer then 2000 characters and the browser does not support CORS, log a warning
} else {
warn('a request to ' + url + ' was longer then 2000 characters and this browser cannot make a cross-domain post request. Please use a proxy https://developers.arcgis.com/esri-leaflet/api-reference/request/');
return;
}
return httpRequest;
}
export function jsonp (url, params, callback, context) {
window._EsriLeafletCallbacks = window._EsriLeafletCallbacks || {};
var callbackId = 'c' + callbacks;
params.callback = 'window._EsriLeafletCallbacks.' + callbackId;
window._EsriLeafletCallbacks[callbackId] = function (response) {
if (window._EsriLeafletCallbacks[callbackId] !== true) {
var error;
var responseType = Object.prototype.toString.call(response);
if (!(responseType === '[object Object]' || responseType === '[object Array]')) {
error = {
error: {
code: 500,
message: 'Expected array or object as JSONP response'
}
};
response = null;
}
if (!error && response.error) {
error = response;
response = null;
}
callback.call(context, error, response);
window._EsriLeafletCallbacks[callbackId] = true;
}
};
var script = DomUtil.create('script', null, document.body);
script.type = 'text/javascript';
script.src = url + '?' + serialize(params);
script.id = callbackId;
script.onerror = function (error) {
if (error && window._EsriLeafletCallbacks[callbackId] !== true) {
// Can't get true error code: it can be 404, or 401, or 500
var err = {
error: {
code: 500,
message: 'An unknown error occurred'
}
};
callback.call(context, err);
window._EsriLeafletCallbacks[callbackId] = true;
}
};
DomUtil.addClass(script, 'esri-leaflet-jsonp');
callbacks++;
return {
id: callbackId,
url: script.src,
abort: function () {
window._EsriLeafletCallbacks._callback[callbackId]({
code: 0,
message: 'Request aborted.'
});
}
};
}
var get = ((Support.cors) ? xmlHttpGet : jsonp);
get.CORS = xmlHttpGet;
get.JSONP = jsonp;
export function warn () {
if (console && console.warn) {
console.warn.apply(console, arguments);
}
}
// choose the correct AJAX handler depending on CORS support
export { get };
// always use XMLHttpRequest for posts
export { xmlHttpPost as post };
// export the Request object to call the different handlers for debugging
export var Request = {
request: request,
get: get,
post: xmlHttpPost
};
export default Request;