如何阻止Google Cloud Functions缓存请求响应结果?
Google Cloud Functions 响应缓存异常问题排查与解决
环境与代码实现
我在Google Cloud Functions(非Firebase Cloud Functions)中部署了一个基于Flask的HTTP函数,根据请求头中的Authorization token返回对应权限的数据:
云函数代码
@functions_framework.http def main(request): token = request.headers['Authorization'] data: List[str] = my_store.get_authorized_data(token) print(data) return data
部署命令
gcloud functions deploy myfunc \ --entry-point main \ --project=myproj \ --trigger-http \ --runtime=python39 \ --allow-unauthenticated \ --timeout=540 \ --memory=1024MB \ --min-instances 1
前端调用代码
前端是部署在Firebase Hosting的React/TypeScript应用,使用axios调用云函数:
axios.get(`cloud/function/url`, { headers: { Accept: "application/json, text/plain, */*", Authorization: `Bearer ${token}`, }, }) .then((result) => { console.log(result.data); return result.data; });
问题现象
- 使用全权限token(可访问
['a', 'b', 'c'])请求时,云函数日志和前端返回结果均正确; - 切换至限权token(仅访问
['a', 'b'])请求时,结果也正常; - 再次切回全权限token时出现异常:云函数日志输出
['a', 'b', 'c'],但前端/curl返回旧数据['a', 'b']; - 问题呈间歇性,约半数请求返回正确结果,另一半返回旧数据,但所有云函数日志均显示正确数据,疑似响应被缓存。
已尝试的无效方案
- 重新部署云函数:仅暂时解决,切换token后问题复现;
- 重新部署前端至Firebase:无效果;
- 禁用浏览器缓存:无效果;
- 在Firebase Hosting设置
Cache-Control: max-age=0:无效果; - 在axios请求中添加时间戳、设置缓存相关请求头:无效果。
后端数据逻辑补充
权限数据存储在Firestore中,文档以用户邮箱命名,字段为允许访问的数据项:
user1@example.com: {a: null, b: null, c: null} user2@example.com: {a: null, b: null}
get_authorized_data函数解析token获取用户邮箱,再从Firestore读取对应数据:
from firebase_admin import auth, firestore db = firestore.client() def get_authorized_data(token): decoded_token = auth.verify_id_token(token) document = db.collection(u'allowed-data-per-user')\ .document(decoded_token['email']).get() allowed_data = list(document.to_dict().keys()) return allowed_data
云函数中print(data)始终输出正确结果,排除该逻辑问题。
解决方案建议
1. 强制设置响应头禁止缓存
Google Cloud Functions的前端层可能会对响应进行缓存,需在返回结果时明确添加禁止缓存的响应头,确保每个请求都返回最新数据:
@functions_framework.http def main(request): token = request.headers['Authorization'] data: List[str] = my_store.get_authorized_data(token) print(data) # 添加禁止缓存的响应头 return ( data, 200, { "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0", "Pragma": "no-cache", "Expires": "0" } )
2. 强制Firestore从服务器获取数据
虽然当前print(data)输出正确,但可强制Firestore客户端跳过本地缓存,直接从服务器读取最新数据:
document = db.collection(u'allowed-data-per-user')\ .document(decoded_token['email']).get(source=firestore.Source.SERVER)
3. 检查实例复用的潜在影响
由于设置了--min-instances 1,云函数实例会被复用,但当前日志显示逻辑执行正确,因此该因素可能性较低。若问题仍存在,可尝试临时移除--min-instances参数测试。
内容的提问来源于stack exchange,提问作者Student
相关产品推荐
相关产品推荐

