/** * 前端请求封装。 * - 游客会话走 cookie(credentials: include),会话失效由服务端重建 * - 浏览器无法改写 User-Agent;X-Real-IP 由服务端反代上游时注入 * - 直连上游时若需自定义头,请走本站 Go 代理接口 */ (function (global) { var DEFAULT_TIMEOUT_MS = 30000; function buildQuery(params) { if (!params) return ""; var pairs = []; Object.keys(params).forEach(function (key) { var value = params[key]; if (value == null) return; pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(value))); }); return pairs.length ? "?" + pairs.join("&") : ""; } /** * @param {string} url * @param {{ * method?: string, * data?: any, * params?: Record, * headers?: Record, * timeout?: number, * }} [options] */ function request(url, options) { options = options || {}; var method = String(options.method || "GET").toUpperCase(); var headers = Object.assign( { Accept: "application/json" }, options.headers || {} ); var finalUrl = url + buildQuery(options.params); var body; var controller = typeof AbortController !== "undefined" ? new AbortController() : null; var timer; if (options.data != null && method !== "GET" && method !== "HEAD") { if (typeof FormData !== "undefined" && options.data instanceof FormData) { body = options.data; } else { headers["Content-Type"] = headers["Content-Type"] || "application/json"; body = headers["Content-Type"].indexOf("application/json") >= 0 ? JSON.stringify(options.data) : options.data; } } var fetchOpts = { method: method, headers: headers, credentials: "include", signal: controller ? controller.signal : undefined, }; if (body != null) fetchOpts.body = body; var timeoutMs = typeof options.timeout === "number" ? options.timeout : DEFAULT_TIMEOUT_MS; if (controller && timeoutMs > 0) { timer = setTimeout(function () { controller.abort(); }, timeoutMs); } return fetch(finalUrl, fetchOpts) .then(function (res) { var contentType = res.headers.get("content-type") || ""; var parse = contentType.indexOf("application/json") >= 0 ? res.json() : res.text(); return parse.then(function (data) { if (!res.ok) { var err = new Error( (data && data.msg) || (data && data.message) || res.statusText || "request failed" ); err.status = res.status; err.code = data && data.code; err.data = data; throw err; } return data; }); }) .finally(function () { if (timer) clearTimeout(timer); }); } global.HttpRequest = { request: request, get: function (url, options) { return request(url, Object.assign({}, options, { method: "GET" })); }, post: function (url, data, options) { return request(url, Object.assign({}, options, { method: "POST", data: data })); }, }; })(typeof window !== "undefined" ? window : this);