2017-01-02 23 views
5

我想从AWS API网关方法返回1px gif。AWS网关API base64Decode产生乱码?

由于二进制数据现在支持,我用下面的“合并响应”映射返回图像/ GIF:

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

然而,当我在Chrome看看这个,我看到了以下这些二进制返回:

enter image description here

相反的:

enter image description here

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

非常感谢提前,这已经造成了我很多的痛苦!

编辑

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

这让我通过网关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,但我希望这将是固定与网关API二进制支持。不幸的是image/bmp不适用于我的用例,因为它不能透明...

如果它有帮助,this has been a good tool用于在base64和hex之间转换。

+0

不响应头是什么样子的Chrome浏览器? –

+0

谢谢,响应标题是: 'HTTP/1。1 200 OK Content-Type:image/gif Content-Length:52 Connection:keep-alive Date:Mon,02 Jan 2017 22:08:55 GMT x-amzn-RequestId:0d3f620c-d138-11e6- 941A-0f16afc9bdc4 X-AMZN-痕量-ID:根= 1-586acf77-93ce6c87faa62ee76758abf5 X-缓存:小姐从CloudFront的 途经:1.1 227087338674ca3d3d23a79539f2998b.cloudfront.net(CloudFront的) X-AMZ-CF-ID:9V1XUr1cPqjm7Bj2HOFfakLlFM5MWo_Ucuv9cdk35xsBz_xhcPvixQ = =' 和响应回来为: '数据:图像/ GIF; BASE64,R0lGODlhAQABAO +/vQAAAAAA77 + 977 + 977 + 9Ie +/vQQBAAAAACwAAAAAAQABAAACAUQAOw ==' – rjmurt

+0

什么是你的API网关的后台?它是Lambda吗? –

回答

6

看起来,这是以前的已知问题: 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

下面是返回编码PNG作为一个字符串的base64我的lambda函数: https://gist.github.com/davemaple/73ce3c2c69d5310331395a0210069263

我更新的方法回应如下: api gateway binary method response

我更新包含硬编码图像/ 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"}]' 

我希望这有助于。

+1

感谢您的帮助Dave,我在上面添加了我的调查的更多细节。会非常感兴趣的听你如何继续! – rjmurt

+0

让我知道,如果你有机会审查这个工作。 –

+1

哇,工作!我不能够感谢你。我不会发现的! – rjmurt

0

结账this answer。它帮助我通过GET请求公开PDF文件进行下载,而无需任何额外的头文件。

1

为了这个别人有问题:我也敲我的头撞在墙上试图从拉姆达无线检索API网关代理集成二进制图像,但后来我发现,它说,那里的LAMBDA控制台的二进制支持部分:

API网关将着眼于的Content-Type接受 HTTP标头决定如何处理尸体。

因此,我将Accept: image/png添加到请求标头,它工作。哦,欢乐,欢乐! 无需手动将内容处理更改为CONVERT_TO_BINARY或使用cli查看。当然,这可以直接使用,例如,<img src=(不能设置标题)。

因此,为了克服API网关从拉姆达与代理集成二进制文件:

  • 列出所有支持的二进制内容类型的拉姆达控制台(和部署)
  • 请求Accept头必须包括从λ表达式
  • 返回的身体必须base64编码返回的Content-Type头
  • 结果对象还必须具有isBase64Encoded属性设置为true

代码:

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