概述
本指南介绍如何在 Web 前端应用中集成 Endfield API,包括认证流程、数据获取和最佳实践。认证策略
Web 前端推荐使用三级降级认证:Copy
JWT(已登录)→ Anonymous Token(游客)→ 无认证(公开端点)
实现参考
Copy
async function fetchAPI(endpoint, options = {}) {
const headers = { 'Content-Type': 'application/json' };
// 1. 优先使用 JWT
const accessToken = localStorage.getItem('access_token');
if (accessToken) {
headers['Authorization'] = `Bearer ${accessToken}`;
} else {
// 2. 降级到 Anonymous Token
let anonToken = localStorage.getItem('anonymous_token');
if (!anonToken) {
anonToken = await obtainAnonymousToken();
}
if (anonToken) {
headers['X-Anonymous-Token'] = anonToken;
}
}
// 3. 附加 Framework Token(如有)
const frameworkToken = localStorage.getItem('framework_token');
if (frameworkToken) {
headers['X-Framework-Token'] = frameworkToken;
}
const response = await fetch(`https://api.end.shallow.ink${endpoint}`, {
...options,
headers: { ...headers, ...options.headers }
});
const data = await response.json();
// 处理 401:尝试刷新 Token
if (response.status === 401 && accessToken) {
const refreshed = await refreshAccessToken();
if (refreshed) return fetchAPI(endpoint, options);
}
if (data.code !== 0) throw new Error(data.message);
return data.data;
}
图片代理
森空岛 CDN 图片有防盗链限制,需要通过代理加载:Copy
function getProxyImageUrl(imageUrl) {
const proxyDomains = ['bbs.hycdn.cn', 'ak.hycdn.cn', 'web.hycdn.cn'];
try {
const url = new URL(imageUrl);
if (proxyDomains.some(d => url.host.endsWith(d))) {
return `https://api.end.shallow.ink/api/proxy/image?url=${encodeURIComponent(imageUrl)}`;
}
} catch {}
return imageUrl;
}
常见场景
展示 Wiki 数据
Copy
// 获取干员列表
const categories = await fetchAPI('/api/wiki/categories');
const operators = await fetchAPI('/api/wiki/items?main_type_id=1&sub_type_id=1');
// 搜索
const results = await fetchAPI('/api/wiki/search?q=近卫');
展示蓝图库
Copy
// 蓝图列表(支持筛选和排序)
const blueprints = await fetchAPI('/api/blueprints?sort=-likes_count&page=1&page_size=20');
// 蓝图详情
const detail = await fetchAPI(`/api/blueprints/${blueprintId}`);
展示抽卡统计
Copy
// 全服统计(公开接口,无需认证)
const globalStats = await fetchAPI('/api/endfield/gacha/global-stats');
// 个人记录(需要 Framework Token)
const records = await fetchAPI('/api/endfield/gacha/records');