一、背景场景
在某类生成任务中,例如用户点击“执行任务”按钮后触发一个较耗时的后端操作(如生成报告、渲染图像、转码视频等),由于其调用了模型、渲染服务或需要较长处理时间,为了防止接口被频繁恶意调用,系统需要加入风控验证机制。
此外,因任务处理为异步,前端无法立即获得最终结果,因此需通过轮询方式定期查询任务状态,等待任务完成后展示结果。
二、整体流程说明
1. 用户点击“执行任务”按钮:
- 前端调用风控接口
/api/risk/check
- 若命中频控规则,弹出验证码组件(如滑块验证)
- 验证通过后继续发起任务请求
- 验证失败提示用户,保留输入内容并刷新验证组件
2. 验证通过后:
- 前端调用
/api/startTask
发起异步任务 - 后端返回任务ID
taskId
- 前端开启轮询,请求
/api/task/status?taskId=xxx
- 当轮询返回
done
,展示结果或跳转
三、技术方案模块拆解
1. 风控接口 /api/risk/check
- 用于检查当前用户/IP 是否触发频控策略
- 返回:是否需要验证、verifyToken(如需)
2. 验证模块
- 接入验证服务(滑块、人机验证)
- 验证成功后自动触发原始任务逻辑
- 验证失败刷新组件并提示用户
3. 任务发起接口 /api/startTask
- 发起耗时任务并返回 taskId
- 可附带验证 token(若有)
4. 轮询接口 /api/task/status?taskId=xxx
- 查询任务状态
- 典型状态值:
pending
,done
,failed
- 建议每 2-3 秒轮询一次,限制最大轮询时长/次数
四、前端核心逻辑示意
async function handleExecute() {const riskRes = await fetch('/api/risk/check');if (riskRes.needVerify) {openVerifyModal(riskRes.verifyToken);} else {await startAndPollTask();}
}async function onVerifySuccess(verifyToken) {await startAndPollTask(verifyToken);
}async function startAndPollTask(verifyToken?) {const { taskId } = await fetch('/api/startTask', { body: { verifyToken } });const timer = setInterval(async () => {const res = await fetch(`/api/task/status?taskId=${taskId}`);if (res.status === 'done') {clearInterval(timer);renderResult(res.result);}}, 3000);
}
五、总结
阶段 | 是否需要轮询 | 原因 |
---|---|---|
风控验证 | ❌ 不需要 | 验证同步完成 |
异步任务处理 | ✅ 需要 | 后端处理耗时,需等待任务完成 |
验证通过后只需继续执行原来的任务逻辑;轮询是异步任务必要的状态确认机制,不是风控逻辑的一部分。
该方案可复用于所有“异步任务 + 防滥用风控 + 前端轮询确认”的场景,如:内容生成、文件上传处理、智能翻译、AI摘要、渲染转码等任务链。