UNPKG

esri-leaflet

Version:

Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services.

223 lines (177 loc) 6.33 kB
import L from 'leaflet'; import Support from './Support'; import { warn } from './Util'; var callbacks = 0; function serialize (params) { var data = ''; params.f = params.f || 'json'; for (var key in params) { if (params.hasOwnProperty(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); } } return data; } function createRequest (callback, context) { var httpRequest = new window.XMLHttpRequest(); httpRequest.onerror = function (e) { httpRequest.onreadystatechange = L.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 = L.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'); 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; } } 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; // get around ie10/11 bug which requires that 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'); } if (typeof context !== 'undefined' && context !== null) { if (typeof context.options !== 'undefined') { httpRequest.timeout = context.options.timeout; } } // request is less then 2000 characters and the browser supports CORS, make GET request with XMLHttpRequest if (requestLength <= 2000 && Support.cors) { httpRequest.send(null); // request is less more then 2000 characters and the browser supports CORS, make POST request with XMLHttpRequest } else if (requestLength > 2000 && Support.cors) { httpRequest.send(paramString); // request is less more then 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 http://esri.github.io/esri-leaflet/api-reference/request.html'); 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 = L.DomUtil.create('script', null, document.body); script.type = 'text/javascript'; script.src = url + '?' + serialize(params); script.id = callbackId; 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; // 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;