GCP Cloud Function浏览器GET请求触发多次执行问题求助
GCP Cloud Function通过浏览器GET请求触发时重复执行三次的原因及解决办法
在执行HTTPS触发的GCP Cloud Function时,通过脚本发起POST请求仅触发函数一次,但使用Edge或Chrome浏览器发起GET请求时,函数会被执行约三次。相关函数代码如下:
@functions_framework.http def sample_function(request): """HTTP Cloud Function. Args: request (flask.Request): The request object. <https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data> Returns: The response text, or any set of values that can be turned into a Response object using `make_response` <https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>. """ if request.method == "OPTIONS": # Allows GET requests from any origin with the Content-Type # header and caches preflight response for an 3600s headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST", "Access-Control-Allow-Headers": "Content-Type", "Access-Control-Max-Age": "3600", } return ("", 204, headers) output = do_something(request) headers = {"Access-Control-Allow-Origin": "*"} return (output, 200, headers)
核心原因
这三次请求并非手动触发的单次请求重复,而是浏览器或其内置服务自动发起的额外请求叠加导致:
- 浏览器预加载机制:Chrome和Edge的预加载/预渲染服务(对应日志里的
MicrosoftPreview/2.0User-Agent)会提前发起请求,预加载可能需要的资源,从而额外触发云函数。 - 内置服务请求:日志中的
OneOutlook/1.2023.1114.100User-Agent表明,微软Outlook相关的后台服务可能主动访问了云函数地址,产生额外调用。 - (可选)图标请求:部分浏览器会自动请求
favicon.ico,如果云函数未处理该路径,也会触发执行,但本次场景中主要是前两类请求。
验证步骤
在函数中添加日志,打印每次请求的路径和User-Agent,明确请求来源:
import logging @functions_framework.http def sample_function(request): logging.info(f"Request path: {request.path}, User-Agent: {request.headers.get('User-Agent')}") # 原有业务代码...
查看云函数日志,就能清楚区分每一次请求的发起方和触发原因。
解决办法
1. 过滤非业务请求
根据User-Agent或请求路径,针对性拦截自动发起的请求,避免触发核心业务逻辑:
@functions_framework.http def sample_function(request): user_agent = request.headers.get('User-Agent', '') # 拦截预加载和OneOutlook的请求 if 'MicrosoftPreview' in user_agent or 'OneOutlook' in user_agent: headers = {"Access-Control-Allow-Origin": "*"} return ("", 200, headers) # 原有业务代码...
注意:先通过日志确认请求特征后再过滤,避免误拦截正常用户请求。
2. 禁用浏览器预加载
在响应头中添加标识,告知浏览器不要预加载该地址:
headers = { "Access-Control-Allow-Origin": "*", "X-Robots-Tag": "noindex, nofollow" } return (output, 200, headers)
3. 处理图标请求(如有)
如果日志中出现/favicon.ico路径的请求,专门处理该路径:
if request.path == '/favicon.ico': return ('', 404)
内容的提问来源于stack exchange,提问作者Tak
相关产品推荐
相关产品推荐

