Files
wordpress-theme-aksrt/assets/js/core/request.js
T

176 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AKSRT frontend request adapter.
*
* Owns the injected REST root, nonce headers, response envelopes, and
* abort-aware error normalization used by modal loaders.
*
* @package AKSRT
*/
(function (window) {
"use strict";
function data() {
return window.aksrtData || window.aksrt || {};
}
function createIdempotencyKey() {
if (window.crypto && typeof window.crypto.randomUUID === "function") {
return window.crypto.randomUUID();
}
if (!window.crypto || typeof window.crypto.getRandomValues !== "function") {
throw new Error("当前浏览器无法生成安全的操作标识");
}
var bytes = new Uint8Array(16);
window.crypto.getRandomValues(bytes);
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
var hex = Array.prototype.map.call(bytes, function (value) {
return value.toString(16).padStart(2, "0");
}).join("");
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
}
function restBase() {
var config = data();
var raw = config.restUrl || config.apiUrl || config.rest_url || "";
var siteUrl = config.siteUrl || config.homeUrl || (window.location.origin + "/");
if (window.location.protocol === "https:" && siteUrl.substring(0, 5) === "http:") {
siteUrl = "https:" + siteUrl.substring(5);
}
if (raw) return String(raw).replace(/\/$/, "");
return String(siteUrl).replace(/\/$/, "") + "/index.php?rest_route=/aksrt/v1";
}
function appendQuery(url, query) {
if (!query) return url;
var parts = [];
if (typeof query === "string") {
parts = query.replace(/^\?/, "").split("&").filter(Boolean);
} else if (typeof query === "object") {
Object.keys(query).forEach(function (key) {
if (query[key] === undefined || query[key] === null) return;
parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(query[key])));
});
}
if (!parts.length) return url;
return url + (url.indexOf("?") >= 0 ? "&" : "?") + parts.join("&");
}
function url(path, query) {
path = String(path || "");
var inlineQuery = "";
var queryIndex = path.indexOf("?");
if (queryIndex >= 0) {
inlineQuery = path.slice(queryIndex + 1);
path = path.slice(0, queryIndex);
}
if (/^https?:\/\//i.test(path)) {
return appendQuery(path, query || inlineQuery);
}
if (path.charAt(0) !== "/") path = "/" + path;
var base = restBase();
var result = base.indexOf("rest_route=") >= 0 ? base + path : base + path;
return appendQuery(result, query || inlineQuery);
}
function headers(options) {
var config = data();
var source = (options && options.headers) || {};
var result = {};
var nonce = config.restNonce || config.nonce || "";
Object.keys(source).forEach(function (key) {
result[key] = source[key];
});
if (!result.Accept) result.Accept = "application/json, text/html;q=0.9, */*;q=0.8";
if (nonce && !result["X-WP-Nonce"]) result["X-WP-Nonce"] = nonce;
if (options && options.body !== undefined && options.body !== null &&
!(window.FormData && options.body instanceof window.FormData) &&
!result["Content-Type"]) {
result["Content-Type"] = "application/json";
}
return result;
}
function responseError(result) {
var json = result.json;
var message = json && (json.message || (json.data && json.data.message));
var error = new Error(message || (result.status ? "请求失败(HTTP " + result.status + ")" : "请求失败"));
error.status = result.status;
error.code = result.status === 401 ? "unauthorized" : "http_error";
error.response = result;
error.json = json;
return error;
}
function parseResponse(response) {
return response.text().then(function (text) {
var type = (response.headers.get("content-type") || "").toLowerCase();
var json = null;
var trimmed = String(text || "").trim();
if (type.indexOf("application/json") >= 0 || trimmed.charAt(0) === "{" || trimmed.charAt(0) === "[") {
try {
json = trimmed ? JSON.parse(trimmed) : {};
} catch (error) {
json = null;
}
}
return {
ok: response.ok,
status: response.status,
headers: response.headers,
text: text,
json: json,
data: json && json.data !== undefined ? json.data : json,
};
});
}
function request(path, options) {
options = Object.assign({}, options || {});
var requestUrl = url(path, options.query);
delete options.query;
var fetchOptions = Object.assign({}, options, {
credentials: options.credentials || "same-origin",
headers: headers(options),
});
return window.fetch(requestUrl, fetchOptions).then(function (response) {
return parseResponse(response);
}).then(function (result) {
if (!result.ok || (result.json && result.json.success === false)) {
throw responseError(result);
}
return result;
});
}
window.AksrtRequest = {
url: url,
request: request,
createIdempotencyKey: createIdempotencyKey,
get: function (path, options) {
return request(path, Object.assign({}, options || {}, { method: "GET" }));
},
post: function (path, body, options) {
return request(path, Object.assign({}, options || {}, {
method: "POST",
body: body,
}));
},
};
})(window);