| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- /**
- * DevExtreme (core/utils/ajax.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var Deferred = require("./deferred").Deferred;
- var domAdapter = require("../../core/dom_adapter");
- var httpRequest = require("../../core/http_request");
- var windowUtils = require("../../core/utils/window");
- var window = windowUtils.getWindow();
- var extendFromObject = require("./extend").extendFromObject;
- var isDefined = require("./type").isDefined;
- var Promise = require("../polyfills/promise");
- var injector = require("./dependency_injector");
- var SUCCESS = "success";
- var ERROR = "error";
- var TIMEOUT = "timeout";
- var NO_CONTENT = "nocontent";
- var PARSER_ERROR = "parsererror";
- var isStatusSuccess = function(status) {
- return 200 <= status && status < 300
- };
- var hasContent = function(status) {
- return 204 !== status
- };
- var paramsConvert = function(params) {
- var result = [];
- for (var name in params) {
- var value = params[name];
- if (void 0 === value) {
- continue
- }
- if (null === value) {
- value = ""
- }
- result.push(encodeURIComponent(name) + "=" + encodeURIComponent(value))
- }
- return result.join("&")
- };
- var createScript = function(options) {
- var script = domAdapter.createElement("script");
- for (var name in options) {
- script[name] = options[name]
- }
- return script
- };
- var removeScript = function(scriptNode) {
- scriptNode.parentNode.removeChild(scriptNode)
- };
- var appendToHead = function(element) {
- return domAdapter.getHead().appendChild(element)
- };
- var evalScript = function(code) {
- var script = createScript({
- text: code
- });
- appendToHead(script);
- removeScript(script)
- };
- var evalCrossDomainScript = function(url) {
- var script = createScript({
- src: url
- });
- return new Promise(function(resolve, reject) {
- var events = {
- load: resolve,
- error: reject
- };
- var loadHandler = function(e) {
- events[e.type]();
- removeScript(script)
- };
- for (var event in events) {
- domAdapter.listen(script, event, loadHandler)
- }
- appendToHead(script)
- })
- };
- var getAcceptHeader = function(options) {
- var dataType = options.dataType || "*";
- var scriptAccept = "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript";
- var accepts = {
- "*": "*/*",
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript",
- jsonp: scriptAccept,
- script: scriptAccept
- };
- extendFromObject(accepts, options.accepts, true);
- return accepts[dataType] ? accepts[dataType] + ("*" !== dataType ? ", */*; q=0.01" : "") : accepts["*"]
- };
- var getContentTypeHeader = function(options) {
- var defaultContentType;
- if (options.data && !options.upload && "GET" !== getMethod(options)) {
- defaultContentType = "application/x-www-form-urlencoded;charset=utf-8"
- }
- return options.contentType || defaultContentType
- };
- var getDataFromResponse = function(xhr) {
- return xhr.responseType && "text" !== xhr.responseType || "string" !== typeof xhr.responseText ? xhr.response : xhr.responseText
- };
- var postProcess = function(deferred, xhr, dataType) {
- var data = getDataFromResponse(xhr);
- switch (dataType) {
- case "jsonp":
- evalScript(data);
- break;
- case "script":
- evalScript(data);
- deferred.resolve(data, SUCCESS, xhr);
- break;
- case "json":
- try {
- deferred.resolve(JSON.parse(data), SUCCESS, xhr)
- } catch (e) {
- deferred.reject(xhr, PARSER_ERROR, e)
- }
- break;
- default:
- deferred.resolve(data, SUCCESS, xhr)
- }
- };
- var isCrossDomain = function(url) {
- if (!windowUtils.hasWindow()) {
- return true
- }
- var crossDomain = false;
- var originAnchor = domAdapter.createElement("a");
- var urlAnchor = domAdapter.createElement("a");
- originAnchor.href = window.location.href;
- try {
- urlAnchor.href = url;
- urlAnchor.href = urlAnchor.href;
- crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host
- } catch (e) {
- crossDomain = true
- }
- return crossDomain
- };
- var setHttpTimeout = function(timeout, xhr) {
- return timeout && setTimeout(function() {
- xhr.customStatus = TIMEOUT;
- xhr.abort()
- }, timeout)
- };
- var getJsonpOptions = function(options) {
- if ("jsonp" === options.dataType) {
- var random = Math.random().toString().replace(/\D/g, "");
- var callbackName = options.jsonpCallback || "dxCallback" + Date.now() + "_" + random;
- var callbackParameter = options.jsonp || "callback";
- options.data = options.data || {};
- options.data[callbackParameter] = callbackName;
- return callbackName
- }
- };
- var getRequestOptions = function(options, headers) {
- var params = options.data;
- var paramsAlreadyString = "string" === typeof params;
- var url = options.url || window.location.href;
- if (!paramsAlreadyString && !options.cache) {
- params = params || {};
- params._ = Date.now()
- }
- if (params && !options.upload) {
- if (!paramsAlreadyString) {
- params = paramsConvert(params)
- }
- if ("GET" === getMethod(options)) {
- if ("" !== params) {
- url += (url.indexOf("?") > -1 ? "&" : "?") + params
- }
- params = null
- } else {
- if (headers["Content-Type"] && headers["Content-Type"].indexOf("application/x-www-form-urlencoded") > -1) {
- params = params.replace(/%20/g, "+")
- }
- }
- }
- return {
- url: url,
- parameters: params
- }
- };
- var getMethod = function(options) {
- return (options.method || "GET").toUpperCase()
- };
- var getRequestHeaders = function(options) {
- var headers = options.headers || {};
- headers["Content-Type"] = headers["Content-Type"] || getContentTypeHeader(options);
- headers.Accept = headers.Accept || getAcceptHeader(options);
- if (!options.crossDomain && !headers["X-Requested-With"]) {
- headers["X-Requested-With"] = "XMLHttpRequest"
- }
- return headers
- };
- var sendRequest = function(options) {
- var xhr = httpRequest.getXhr();
- var d = new Deferred;
- var result = d.promise();
- var async = isDefined(options.async) ? options.async : true;
- var dataType = options.dataType;
- var timeout = options.timeout || 0;
- var timeoutId;
- options.crossDomain = isCrossDomain(options.url);
- var needScriptEvaluation = "jsonp" === dataType || "script" === dataType;
- if (void 0 === options.cache) {
- options.cache = !needScriptEvaluation
- }
- var callbackName = getJsonpOptions(options);
- var headers = getRequestHeaders(options);
- var requestOptions = getRequestOptions(options, headers);
- var url = requestOptions.url;
- var parameters = requestOptions.parameters;
- if (callbackName) {
- window[callbackName] = function(data) {
- d.resolve(data, SUCCESS, xhr)
- }
- }
- if (options.crossDomain && needScriptEvaluation) {
- var reject = function() {
- d.reject(xhr, ERROR)
- };
- var resolve = function() {
- if ("jsonp" === dataType) {
- return
- }
- d.resolve(null, SUCCESS, xhr)
- };
- evalCrossDomainScript(url).then(resolve, reject);
- return result
- }
- if (options.crossDomain && !("withCredentials" in xhr)) {
- d.reject(xhr, ERROR);
- return result
- }
- xhr.open(getMethod(options), url, async, options.username, options.password);
- if (async) {
- xhr.timeout = timeout;
- timeoutId = setHttpTimeout(timeout, xhr, d)
- }
- xhr.onreadystatechange = function(e) {
- if (4 === xhr.readyState) {
- clearTimeout(timeoutId);
- if (isStatusSuccess(xhr.status)) {
- if (hasContent(xhr.status)) {
- postProcess(d, xhr, dataType)
- } else {
- d.resolve(null, NO_CONTENT, xhr)
- }
- } else {
- d.reject(xhr, xhr.customStatus || ERROR)
- }
- }
- };
- if (options.upload) {
- xhr.upload.onprogress = options.upload.onprogress;
- xhr.upload.onloadstart = options.upload.onloadstart;
- xhr.upload.onabort = options.upload.onabort
- }
- if (options.xhrFields) {
- for (var field in options.xhrFields) {
- xhr[field] = options.xhrFields[field]
- }
- }
- if ("arraybuffer" === options.responseType) {
- xhr.responseType = options.responseType
- }
- for (var name in headers) {
- if (Object.prototype.hasOwnProperty.call(headers, name) && isDefined(headers[name])) {
- xhr.setRequestHeader(name, headers[name])
- }
- }
- if (options.beforeSend) {
- options.beforeSend(xhr)
- }
- xhr.send(parameters);
- result.abort = function() {
- xhr.abort()
- };
- return result
- };
- module.exports = injector({
- sendRequest: sendRequest
- });
|