公开 API 大数据导出与断点续取
当账号拥有较多记录、成绩或相片时,浏览器一次性加载会导致内存、超时和重复问题。本页给导出工具和高级客户端提供分块读取、断点、校验和取消策略。
导出前估算
导出前确认:
- 当前账号和权限;
- 预计记录数或页数;
- 每页大小;
- 本地可用空间;
- 目标文件是否含个人信息;
- 网络和维护窗口;
- 是否允许导出全部范围。
不要在公共设备或移动网络上无提示执行全量导出。
分块读取
采用固定页大小但按实际返回推进:
js
async function exportRange(readPage, pageSize = 50) {
let start = 0;
const output = [];
while (true) {
const page = await readPage(start, start + pageSize);
const rows = Array.isArray(page.items) ? page.items : [];
output.push(...rows);
if (rows.length === 0 || rows.length < pageSize) break;
start += rows.length;
}
return output;
}实际字段以对应接口为准。导出器应保存当前页起止范围、返回数量和最后一次成功时间。
检查点文件
检查点可以包含:
json
{
"account_alias": "account-a",
"kind": "playlog",
"next_start": 500,
"page_size": 50,
"completed_pages": 10,
"updated_at": "<RFC3339_TIME>",
"output_file": "<PROTECTED_PATH>"
}检查点不应包含 Token、完整账号名、文件内容或地址。它只能在同一账号和同一导出任务中使用。
中断与恢复
发生网络、浏览器关闭或用户取消时:
- 保存最后一个完整页;
- 写入检查点;
- 关闭未完成请求;
- 下次验证 Token;
- 从最后一个未确认范围继续;
- 对重叠范围去重。
不要把“请求已经发出”当成页面已经成功写入检查点。只有解析并验证结构后才推进游标。
去重
优先使用服务返回的稳定记录标识。没有稳定 ID 时保留原始页并采用谨慎的复合键,例如时间、曲目和序号,但要明确这可能误合并。导出完成后报告:总页数、原始条数、去重后条数和疑似重复数。
顺序
服务可能在导出期间新增数据。不要把返回顺序当成永久时间顺序。导出后按字段排序,并保留原始读取范围。跨页出现相同记录时,选择更新时间较新的对象或保留两个版本并标记冲突。
文件导出
导出文件应:
- 保存到受保护位置;
- 使用不包含凭据的文件名;
- 写入导出时间和账号脱敏别名;
- 完成后计算哈希;
- 分享前去掉个人信息;
- 不自动上传到第三方。
图片导出应限制并发和总大小;下载失败时只重试当前文件,不要重新读取全部列表。
取消操作
取消全量导出只停止客户端,不应删除已经保存的文件或服务器数据。UI 要区分“取消导出”和“删除导出文件”,后者需要用户明确操作。
限频和退避
读取请求使用有限并发和退避。遇到 429 时尊重服务提示;遇到 401/403 先停止;遇到解析错误保留原响应摘要,不要快速重试相同错误。
导出完成校验
- [ ] 最后一页已确认;
- [ ] 没有未处理的检查点;
- [ ] 总数和去重数已记录;
- [ ] 数据结构逐页通过校验;
- [ ] 文件可重新解析;
- [ ] 账号和时间范围已记录;
- [ ] 文件位置受保护;
- [ ] 日志没有凭据或个人数据原文;
- [ ] 导出目的和保留时间已明确。
