python - 如何在与 API Gateway 集成的 AWS Lambda python 中执行 302 重定向?
问题描述
我正在尝试使用无服务器架构构建一个非常轻量级的静态网站:
- 用户使用登录信息填充表单
- 向 AWS API Gateway 提交操作路由,然后触发 AWS Lambda Python 函数,该函数将用户登录到 3rd 方站点,获取一些数据并将其保存到 s3
- 保存数据后,我想在客户端向用户提供数据的下载按钮
我尝试在 API Gateway 中使用 302 重定向来执行此操作,无论是否集成 lambda 代理集成,以便我可以将用户重定向到从 s3 提取数据的不同网页。
使用代理集成我每次都会收到内部服务器错误。
没有它,我只是将 json 响应返回给用户,而不是实际的重定向。
这是我的 lambda 函数中响应的 python 代码(这个 json 是当前返回给用户的内容,而不是将它们带到 url https://example.com):
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
},
"multiValueHeaders": {},
"body": "Success!!!"
}
我将“Location”标头添加到 API Gateway 中的方法响应中,并将其映射到集成响应中的 integration.response.headers.location(当我尝试不使用 lambda 代理时)。
不过,这一切都没有成功。
使用代理它的内部服务器错误仅发生在 html 表单中(在 api 网关控制台或 lambda 控制台中测试时不会发生),并且没有代理它不会重定向到 Location 标头中的值,只是打印 json到 api 的 url。
非常感谢任何帮助、指导或建议!
谢谢你的时间。
解决方案
分享我是如何解决这个问题的,以防其他人遇到类似问题。
event
由于我从 API Gateway解析变量的方式,我在使用 Lambda 代理集成时遇到了内部服务器错误。
假设您的 API Gateway 配置为Lambda 代理集成并且您的 Lambda 函数是用 python 编写的,那么当从静态 s3 http 表单触发时,以下代码应该会导致成功的 302 重定向:
import urllib.parse
from furl import furl
def lambda_handler(event, context):
body = urllib.parse.unquote(event["body"])
furledBody = furl("/abc?" + body)
parameter1 = furledBody.args["parameter1"]
parameter2 = furledBody.args["parameter2"]
parameter3 = furledBody.args["parameter3"]
#Do stuff with body parameters
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
}
"multiValueHeaders": {},
"body": ""
}
然而,这不是我为我的用例提供的设计,我的 lambda 函数下载回客户端供用户下载的数据。
相反,我将我的 lambda 响应配置为包含在客户端自动呈现为对 http 表单请求的响应的 html。在 html 中,我包含了之前在 lambda 中生成的 S3 预签名 URL:
import boto3
s3 = boto3.client('s3')
presignedURL = s3.generate_presigned_url('get_object',{'Bucket': '[insert bucket name]', 'Key': '[insert key aka file name including the full path]'}, 500, 'GET'}
responseBody = (
"<html>"
"<head></head>"
"<body>"
"<a href=\"" + presignedURL + "\"download><button>Download</button></a>"
"</body>"
"</html>")
return {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {
"Content-Type": "text/html"
}
"multiValueHeaders": {},
"body": responseBody
}
推荐阅读
- bash - 我需要用 sed 命令删除两个“”
- android - android中的1000个问题需要创建1000个活动?
- django - Django“模型”对象不可迭代
- sql-server - 在 SSMS 与应用程序服务器中创建 SQL Server 查询计划
- bash - 禁用特定用户登录的 sudo 密码
- java - 没有 @Bean 的简单 Spring Java @Configuration 到 @Autowire
- python - 如何从 java 源代码(从文件)中删除在 python 中只有一个左括号或右括号的行?
- javascript - 在 spark ar 环境中获取变形对象
- apache-nifi - 当 putSQL 失败时停止 CaptureChangeMySQL
- php - 为自托管的播客提要创建面向未来的 URL