Flask调用带回调的API服务时如何将回调响应返回给前端客户端
问题解决思路
你当前的核心矛盾是:第三方API采用异步回调模式返回结果,前端发起的初始AJAX请求链路和第三方回调的链路是完全独立的,没有办法通过原有请求直接返回回调结果,需要通过状态共享+主动通知的方式实现结果同步。
方案1:短轮询(实现成本最低,推荐中小项目使用)
实现步骤
- 第一步:改造
/api-req接口,生成唯一请求ID关联业务
import uuid import json import redis # 单实例部署也可以用全局字典做缓存,不用额外装依赖 r = redis.Redis(host='localhost', port=6379, db=0) @public.route('/api-req', methods=['POST']) def api_req(): d1 = request.form['d1'] d2 = request.form['d2'] # 生成唯一请求ID req_id = str(uuid.uuid4()) # 缓存请求初始状态,5分钟自动过期 r.setex(f"req:{req_id}", 300, "pending") api_data = { "d1": d1, "d2": d2, "callbackUrl": f"http://www.myurl.com/api-service/response?req_id={req_id}" } requests.post(api_url, json=api_data) # 直接返回请求ID给前端 return {"code":0, "req_id": req_id}
- 第二步:改造回调接口,收到结果后存入缓存
@public.route('/api-service/response', methods=['POST']) def api_resp(): req_id = request.args.get('req_id') # 拿到第三方返回的结果,根据第三方返回格式调整取值方式 callback_data = request.get_json() # 结果存入缓存 r.setex(f"req:{req_id}", 300, json.dumps(callback_data)) return {"code":0}
- 第三步:新增轮询查询接口,供前端拉取结果
@public.route('/api-query-result', methods=['GET']) def query_result(): req_id = request.args.get('req_id') data = r.get(f"req:{req_id}") if not data or data == b'pending': return {"code":1, "msg":"结果未就绪"} return {"code":0, "data": json.loads(data)}
- 第四步:改造前端AJAX逻辑,拿到req_id后启动轮询
$.ajax({ type: 'POST', url: 'api-req', data: {'d1': '{{ d1 }}', 'd2': d2}, success: function(res) { const reqId = res.req_id // 启动轮询,每2秒查一次结果,可根据业务调整间隔 const timer = setInterval(() => { $.get('api-query-result', {req_id: reqId}, function(queryRes) { if (queryRes.code === 0) { // 拿到结果,清除轮询 clearInterval(timer) // 后续业务逻辑 console.log('第三方返回结果:', queryRes.data) } }) }, 2000) } });
方案2:SSE/长轮询(实时性更高)
如果需要更低的延迟,可以用SSE实现服务端主动推送:
- 前端发起SSE连接,带上请求标识
- 后端持有SSE连接不释放,回调接口收到结果后,通过SSE连接直接推送给前端
- 无需前端频繁轮询,资源占用更低
方案3:WebSocket(适合复杂交互场景)
如果业务本身需要频繁的前后端双向交互,可以预先建立WebSocket连接:
- 前端和后端建立WebSocket连接后,存储用户ID和连接的映射关系
- 回调接口收到结果后,找到对应用户的WebSocket连接,直接推送结果
- 实时性最高,适合需要多轮交互的业务
内容的提问来源于stack exchange,提问作者destinychoice
相关产品推荐
相关产品推荐

