AWS API Gateway base64Decode产生乱码二进制文件?

时间:2017-01-02 15:36:57

标签: amazon-web-services aws-api-gateway

我正在尝试从AWS API网关方法返回1px gif。

由于现在支持二进制数据,我使用以下“集成响应”映射返回image / gif:

$util.base64Decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")

但是,当我在Chrome中查看此内容时,我会看到返回以下二进制文件:

enter image description here

而不是:

enter image description here

有谁能帮助我理解为什么这是乱码和错误的长度?或者我能做些什么来返回正确的二进制文件?还有其他一些我总是可以返回这个1px gif而不使用base64Decode函数吗?

非常感谢,这给我带来了很多痛苦!

修改

这个变得陌生。看起来问题不在于base64Decode,而在于二进制的一般处理。我在this blog postStack Overflow question之后添加了一个Lambda后端(之前我使用的是Firehose)。我按照documentation page将图像设置为binaryMediaType。

这让我可以通过Gateway API从Lambda传递以下图像/ bmp像素,并且它可以正常工作:

exports.handler = function(event, context) {

  var imageHex = "\x42\x4d\x3c\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x06\x00\x00\x00\x27\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00";
  context.done(null, { "body":imageHex });

};

然而,以下代表图像/ png或图像/ gif的图像在通过时会出现乱码:

exports.handler = function(event, context) {

//var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
//var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b";
  var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b\x0a"
  context.done(null, { "body":imageHex });

};

这似乎与another Stack Overflow question的问题相同,但我希望通过Gateway API二进制支持来解决这个问题。不幸的是,image / bmp对我的用例不起作用,因为它不能透明......

如果它可以帮助任何人,this has been a good tool可以在base64和hex之间进行转换。

3 个答案:

答案 0 :(得分:15)

对于其他任何有此问题的人:我还试图通过API网关代理集成 lambda 检索二进制图像,但是然后我注意到它在Lambda控制台的二进制支持部分就是这样说的:

  

API网关将查看内容类型接受 HTTP标头,以决定如何处理正文。

所以我在请求标头中添加了Accept: image/png并且它有效。哦快乐,快乐! 无需手动将内容处理更改为CONVERT_TO_BINARY或使用cli进行清理。当然,这排除了直接使用<img src=(无法设置标题)。

因此,为了通过代理集成的lambda从API网关获取二进制文件:

  • 列出lambda控制台(和部署)中所有支持的二进制内容类型
  • 请求Accept标头必须包含lambda表达式
  • 返回的Content-Type标头
  • 返回的正文必须是base64编码
  • 结果对象还必须将isBase64Encoded属性设置为true

代码:

callback(null, {
    statusCode: 200,
    headers: { 'Content-Type': 'image/png' },
    body: buffer.toString('base64'),
    isBase64Encoded: true
}

答案 1 :(得分:9)

看起来这是以前的一个已知问题: https://forums.aws.amazon.com/thread.jspa?messageID=668306&#668306

但现在它们应该可以添加对二进制数据的支持: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

看起来这就是我们需要的位:“将IntegrationResponse资源的contentHandling属性设置为 CONVERT_TO_BINARY ,以使响应有效负载从Base64编码的字符串转换为其二进制blob”。然后我们不应该需要base64Decode()函数。

立即进行测试,看看是否有效。

编辑:我终于能够正常工作了。你可以在这里看到二进制图像: https://chtskiuz10.execute-api.us-east-1.amazonaws.com/prod/rest/image

这是我的Lambda函数,它将base64编码的PNG作为字符串返回: https://gist.github.com/davemaple/73ce3c2c69d5310331395a0210069263

我更新了方法响应,如下所示: api gateway binary method response

我更新了集成响应以包含硬编码的image / png标头: api gateway binary integration response

最后一步很棘手:将contentHandling属性设置为“CONVERT_TO_BINARY”。我无法弄清楚如何在AWS控制台中执行操作。我必须使用CLI API来完成此任务:

aws apigateway update-integration-response \
    --profile davemaple \
    --rest-api-id chtskiuzxx \
    --resource-id ki1lxx \
    --http-method GET \
    --status-code 200 \
    --patch-operations '[{"op" : "replace", "path" : "/contentHandling", "value" : "CONVERT_TO_BINARY"}]'

我希望这会有所帮助。

答案 2 :(得分:0)

结帐this answer。它帮助我通过GET请求公开PDF文件,无需任何额外的标题。