/** * SGApi —— H5 调 app-server 后端的薄封装。 * * 同源:H5 由 app-server 的 /media/h5/ 托管,后端在 /api/v1,同 host:port → 用相对路径、无 CORS。 * 鉴权:JWT Bearer。token 经 SGBridge.getToken() 从原生取(原生持登录态);浏览器调试走 bridge 的 mock token。 * 401:交原生拉登录(requestLogin)兜底,本次请求按失败 reject;正式的 refresh 重试策略阶段2 再补。 * * 依赖 shared/bridge.js 先加载(取 token)。 */ (function (global) { 'use strict'; var BASE = '/api/v1'; function authHeaders() { var t = (global.SGBridge && global.SGBridge.getToken()) || ''; var h = { 'Content-Type': 'application/json' }; if (t) h['Authorization'] = 'Bearer ' + t; return h; } function handle(res) { if (res.status === 401) { // 未授权:拉原生登录(异步),本次请求按失败处理,调用方自行决定是否重试 if (global.SGBridge) global.SGBridge.requestLogin(); return Promise.reject(new Error('unauthorized')); } if (!res.ok) { return res.text().then(function (t) { return Promise.reject(new Error('http ' + res.status + ' ' + t)); }); } // 204 / 空体兜底 return res.text().then(function (t) { return t ? JSON.parse(t) : null; }); } /** GET /api/v1。path 以 / 开头,如 '/savings/battle'。 */ function apiGet(path) { return fetch(BASE + path, { method: 'GET', headers: authHeaders() }).then(handle); } /** POST /api/v1,body 自动 JSON 序列化。 */ function apiPost(path, body) { return fetch(BASE + path, { method: 'POST', headers: authHeaders(), body: JSON.stringify(body || {}), }).then(handle); } global.SGApi = { base: BASE, get: apiGet, post: apiPost }; })(window);