如何在Lambda中向无CORS内部端点发送GET/POST请求解决HTTP调用失败问题
问题原因与解决方案
首先澄清核心认知:CORS是仅对浏览器前端生效的安全限制,服务端之间的HTTP调用完全不受CORS规则约束,你遇到的调用失败和CORS、“请求为HTTP类型”没有任何关系,失败原因集中在网络配置和代码bug两个维度。
常见失败原因
- 网络配置问题:如果这两个内部端点属于公司内网/私有VPC内的服务,默认运行在AWS公有网络环境的Lambda没有内网访问权限,无法连通内部端点。需要做如下配置:
- 将Lambda部署到和内部端点同一个VPC下
- 配置Lambda关联的安全组出网规则,放通到两个端点443端口的访问权限
- 配置VPC的路由表、内网DNS,确保Lambda可以正常解析两个端点的域名、路由到对应服务
- 如果内部端点配置了IP白名单,需要将Lambda的出口IP(VPC部署的话对应NAT网关的公网IP,公有部署的话对应对应AWS区域的Lambda出口IP段)加入白名单
- 代码bug:你当前提供的代码存在两处会直接导致运行失败的问题:
requests请求返回的response是响应对象,不能直接被json.dumps序列化,需要先调用response.json()获取响应体的字典内容,或者调用response.text获取字符串内容- 处理address请求时,
event['body']是字符串类型,直接传给requests.post的json参数会报错,需要先通过json.loads转成字典格式
修正后的代码
import json import requests import traceback EMAIL_RAW_PATH = '/Validation_API_Stage/email_address' ADDRESS_RAW_PATH = '/Validation_API_Stage/address' EMAIL_URL = 'https://ent-sls-email-validation.msd0xxxx.example.com/v1/validationInfo' ADDRESS_URL = 'https://address.msdxxxx.example.com/data/address_scrub' ADDRESS_HEADERS = { "lob": "Test", "application-name": "Example", "tenant-id": "16", "Content-Type": "application/json" } EMAIL_HEADERS = { 'x-correlation-id': '1234567', 'lob': 'Test', 'application-name': 'Example', 'tenant-id': '20', 'x-api-key': '12345678901234567890', 'Content-Type': 'application/json' } def lambda_handler(event, context): print("收到请求:", json.dumps(event)) try: if event['rawPath'] == ADDRESS_RAW_PATH: # 先把body转成字典 address_body = json.loads(event['body']) response = requests.post(ADDRESS_URL, headers=ADDRESS_HEADERS, json=address_body, timeout=10) # 先打印响应状态和内容方便排查 print("address接口响应状态:", response.status_code) print("address接口响应内容:", response.text) return { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": json.dumps({ "Response": response.json() if response.headers.get('Content-Type') == 'application/json' else response.text }) } elif event['rawPath'] == EMAIL_RAW_PATH: decodedEvent = json.loads(event['body']) EMAIL_ADDRESS = decodedEvent['email'] URL = EMAIL_URL + '?email=' + EMAIL_ADDRESS response = requests.get(URL, headers=EMAIL_HEADERS, timeout=10) print("email接口响应状态:", response.status_code) print("email接口响应内容:", response.text) return { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": json.dumps({ "Response": response.json() if response.headers.get('Content-Type') == 'application/json' else response.text }) } else: return { "statusCode": 404, "body": json.dumps({"error": "路径不匹配"}) } except Exception as e: # 打印完整错误日志方便排查 print("调用出错:", str(e)) print(traceback.format_exc()) return { "statusCode": 500, "body": json.dumps({"error": str(e)}) }
排查建议
部署修正后的代码后,查看Lambda的CloudWatch日志,根据错误信息定位问题:
- 如果是
Connection timeout/Name or service not known错误,优先检查VPC、网络、DNS配置 - 如果是401/403错误,检查请求头的鉴权参数是否正确
- 如果是400错误,检查请求体、请求参数的格式是否符合接口要求
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

