使用带JSON请求体的GET调用AWS API Gateway为何遭CloudFront返回Bad Request?
问题:带JSON请求体的GET请求调用AWS API Gateway REST API时CloudFront返回403错误
问题现象
使用带有application/json类型请求体的GET请求调用API Gateway时,CloudFront返回Bad request(403错误);但使用相同请求头和请求体的POST请求能正常返回结果。该GET方法已配置为Lambda代理集成。
测试的curl命令及结果:
# GET请求(失败) $ curl -XGET --json '{"n": 5}' -H 'Authorization: Bearer foo' -H 'x-gateway-authorization: Bearer bar' 'https://a5t0qb2tfg.execute-api.eu-west-1.amazonaws.com/prod/fib' <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <TITLE>ERROR: The request could not be satisfied</TITLE> </HEAD><BODY> <H1>403 ERROR</H1> <H2>The request could not be satisfied.</H2> <HR noshade size="1px"> Bad request. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner. <BR clear="all"> If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation. <BR clear="all"> <HR noshade size="1px"> <PRE> Generated by cloudfront (CloudFront) Request ID: I4wmI1bt3ddj5uScRwkIU-ONFAiyQCZoYm3BIYMH6LR5QHpK1cM2aw== </PRE> <ADDRESS> </ADDRESS> </BODY></HTML>% # POST请求(成功) $ curl -XPOST --json '{"n": 5}' -H 'Authorization: Bearer foo' -H 'x-gateway-authorization: Bearer bar' 'https://a5t0qb2tfg.execute-api.eu-west-1.amazonaws.com/prod/fib' {"result": 5, "job_id": "55dc052c-2b08-486e-87b6-462abcf24e96"}%
问题原因
- HTTP规范与网关拦截:虽然HTTP标准没有完全禁止GET请求带请求体,但行业通用实践中GET请求通常用于获取资源,不应携带请求体。CloudFront作为CDN网关,默认会拦截这种不符合常规用法的GET请求,直接返回403错误,请求根本没有到达API Gateway层。
- API Gateway代理集成的局限性:尽管配置了Lambda代理集成,但由于CloudFront在前端拦截,请求无法传递到API Gateway进行转发。
解决方案
1. 改用POST请求(推荐)
既然POST请求已经可以正常工作,且后端Lambda已经支持解析JSON请求体,直接使用POST请求是最稳妥的方案,符合HTTP规范的常规用法,也不会触发网关的拦截逻辑。
2. 将JSON参数转为查询字符串(如果必须用GET)
把请求体中的JSON参数拆解为查询字符串参数,例如:
curl -XGET -H 'Authorization: Bearer foo' -H 'x-gateway-authorization: Bearer bar' 'https://a5t0qb2tfg.execute-api.eu-west-1.amazonaws.com/prod/fib?n=5'
同时需要修改后端Lambda函数,从event.queryStringParameters中获取参数,而不是从event.body中解析。
3. 调整CloudFront配置(不推荐)
如果业务场景必须使用GET带请求体,可以通过以下方式调整CloudFront:
- 使用Lambda@Edge或CloudFront函数,在请求转发到API Gateway前保留GET请求的请求体;
- 修改CloudFront的缓存策略,禁用对GET请求体的拦截。
但这种方式违反HTTP通用实践,可能导致其他客户端或中间件的兼容性问题,不建议采用。
内容的提问来源于stack exchange,提问作者Shuzheng
相关产品推荐
相关产品推荐

