2ed62c789f
- h5/mine/index.html: 个人中心「我的页」H5 实现 - h5/shared/bridge.js, api.js: H5↔客户端桥与 API 封装(mine 依赖) Reviewed-on: #89 Co-authored-by: xiebing <xiebing@wonderable.ai> Co-committed-by: xiebing <xiebing@wonderable.ai>
53 lines
1.8 KiB
JavaScript
53 lines
1.8 KiB
JavaScript
/**
|
||
* 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>。path 以 / 开头,如 '/savings/battle'。 */
|
||
function apiGet(path) {
|
||
return fetch(BASE + path, { method: 'GET', headers: authHeaders() }).then(handle);
|
||
}
|
||
|
||
/** POST /api/v1<path>,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);
|