假设我有这个HTML:
<img src="http://example.com/pic"/>
What I would like to do is have example.com/pic map to an AWS API Gateway endpoint.
然后,该端点将调用lambda函数。
lambda函数将从s3桶中读取一个随机图像并返回。
所以我的目标是使用一个STANDARD HTML图像标记,并最终得到一个来自s3桶的图像,但要通过lambda中的一些决策代码来决定要返回的图像。
我知道你可以直接使用s3来提供静态内容(因此使用lambda来决定使用什么图像),我也知道我可以在lambda中做一些事情,比如b64编码响应,然后在客户端处理它,但是我的目标是使用标准的HTML IMG标记。
这可能吗?
我试过使用ResponseStreamHandler(Java SDK)来处理lambda并返回图像的字节数组,还添加了API网关配置以不将输出Map到JSON,但似乎什么都不起作用!
6条答案
按热度按时间myss37ts1#
AWS似乎简化了这一过程,以至于许多答案都过时了和/或过于复杂。
这就是我如何让Lambda通过API Gateway返回图像的方法,截至2018年6月:
1)在API Gateway中,为您的API启用
Use Lambda Proxy integration
。(此设置位于集成请求部分,您已在此处将类型设置为Lambda。2)在API网关中,选择您的API并单击
Settings
。在Binary Media Types
中添加*/*
。(注意:我试着简单地添加"image/jpeg",但似乎需要*/*
才能使所有这些工作)3)确保部署您的API,否则您的更改将不会生效。(在API网关中,选择您的API,然后选择操作〉部署API)。
4)在Lambda代码中,以Base64编码返回图像(此示例为C#代码):
好的。
如果您已经将API设置为不需要身份验证,只需在浏览器中输入API链接,它就会显示图像。或者将API链接放入
IMG
标签中。例如<img src="https://asdf.execute-api.us-east-1.amazonaws.com/live/myapi" />
注意:即使在步骤2中您将
Binary Media Types
设置为*/*
,API Gateway仍然会返回文本(如果这是您的Lambda返回的内容)。n3ipq98p2#
幸运的是,现在AWS API Gateway支持二进制数据,尽管您还需要通过CLI更新资源方法,因为它尚未在控制台中实现。
1.在方法的方法响应中
在HTTP 200状态响应标头中将
Content-Type
设置为image/jpeg
1.在方法的积分响应中
在标题Map中将
Content-Type
设置为'image/jpeg'
。注意引号!1.使用AWS CLI,在集成响应中将
contentHandling
属性设置为CONVERT_TO_BINARY
在这个伟大的分步指南中检查整个过程:https://stackoverflow.com/a/41434295/720665
kzipqqlq3#
我也遇到过类似的问题,如前所述,目前你不能直接从API网关端点返回二进制格式的图像,而这是浏览器正确显示图像所必需的。
然而,我通过让API Gateway返回一个302 Redirect,指向S3中正确的文件来解决这个问题。您可以让Lambda函数返回文件的url,稍后将其Map到API Gateway中的Location头。浏览器将遵循重定向并正确显示图像。
有几种方法可以实现重定向,但我做了如下:
krcsximq4#
需要说明的是,客户端执行两个不同的请求:
1.第一个获取HTML(包括图像url)的。
1.第二个从url中提取图像数据。
换句话说,图像数据未内联在HTML中。
基于这些知识,您可以按照建议使用Lambda(位于API网关之后)。Lambda实现可以包含一些逻辑,用于确定存储在S3中的图像的url。但是,Lambda返回JSON数据而不是HTML(存在return the html in a variable等解决方案),这使得事情变得更加棘手,特别是对于大型HTML页面。
我建议一个稍微不同的方法,因为仅仅接收一个图像标签不会让你走得很远。我假设你会在一个HTML文档中内联图像标签,可能是通过使用JavaScript。然后你也可以让API Gateway / Lambda请求返回一个带有图像url的JSON文档,让JavaScript用新的url更新现有的图像标签,或者为你生成标签。
shyt4zoc5#
目前还不可能,因为您无法通过AWS API Gateway返回二进制数据。
要实现这一点,lambda函数需要以二进制blob的形式返回图像数据,以及一些元信息,如图像内容类型。然后,AWS API Gateway需要能够将其Map到HTTP响应。例如:-
lambda返回:第一个月
则API网关需要将contentTypeMap到响应的“content-type”报头,并将图像数据以正确的编码和长度放入响应的主体中。
不幸的是,它现在还不能这样做,它只将application/json或application/xml这样的文本编码Map为响应类型(毕竟它是为API设计的)。
使用ElasticBeanstalk可以非常容易地实现这一点,在这里您可以对http响应进行更多的控制。
ccgok5k56#
我在重新考虑我的设计时解决了这个问题。潜在的想法是Lambda是好的计算单元和坏的文件服务器。
我变了
变成
Client > APIGW > Lambda > SignedURL
Client(SignedURL) > Image
由于我的客户端是基于Web的,因此在这种转变之后,一切都变得更容易了