AWS无服务器函数未响应图像。

5

我想让AWS API Gateway以图片的形式回复。我的Serverless Lambda代码如下:

const express = require('express');
const serverless = require('serverless-http');
const bodyParser = require('body-parser');
const request = require('request');
const fetch = require('node-fetch')
var Jimp = require('jimp');
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

app.get('/image/:id', async(req, res) => {
    const id = req.params.id;

    var imgUrl = 'https://developer.salesforce.com/forums/profilephoto/729F00000005O41/T';
    let options = {};

    const image = await Jimp.read(imgUrl);
    image.getBuffer(Jimp.MIME_JPEG, (err, buffer) => {
        res.set('content-type', 'image/jpeg');
        res.send(buffer.toString('base64'));
    });
});
// wrap express app instance with serverless http function
module.exports.handler = serverless(app)

serverless.yml


provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: us-east-1
  memorySize: 512

custom:
  apigwBinary:
    types:           #list of mime-types
      - 'image/jpg'
      - 'image/jpeg'
      - 'image/png'
functions:
  avatarFunc:
    handler: index.handler
    events:
      - http:
          path: image/{id}
          method: get
          contentHandling: CONVERT_TO_BINARY

plugins:
  - serverless-offline
  - serverless-apigw-binary

这里返回的图像是一个黑盒子。 这里输入图片描述
2个回答

5

好的。我刚刚仔细阅读了这篇文章,并且想要分享一下解决方案。问题与Serverless和AWS之间的不匹配有关。因此,我们需要让它们保持一致。

首先 -> Serverless配置

const binaryMimeTypes = {binary: [
  'image/*',
  'image/jpeg',
  'image/png',
  'image/svg+xml',
]};

module.exports.server = sls(app, binaryMimeTypes) 

这将配置Serverless以Base64格式提供关联的Mime类型。

第二步-> AWS配置

在AWS API中选择网关,然后选择“设置”。向下滚动并添加以下二进制类型:

AWS配置

就是这样!现在应该可以工作了!


2
我不知道在找到这个之前,我通过了多少次Buffer.from`` res.send``res.end的修订。 AGW /服务器级别! 哎呀。 谢谢! - sonjz

2

在API Gateway中处理二进制文件总是很麻烦。不过我已经成功让它工作了。

你只需要告诉API Gateway你的响应是以base64编码的即可。

以下是一个可行的解决方案:

Original Answer 翻译成“最初的回答”

module.exports.hello = async (event, context) => {
  const imgUrl = 'https://developer.salesforce.com/forums/profilephoto/729F00000005O41/T';
  const image = await jimp.read(imgUrl);
  const buffer = await image.getBufferAsync(jimp.MIME_JPEG);
  return {
    statusCode: 200,
    headers: {
      'content-type': 'image/jpeg'
    },
    body: buffer.toString('base64'),
    isBase64Encoded: true
  };

};

然而,我认为这里真正的问题是Express正在为您管理路由,因此我不认为您可以拦截API GW的响应以添加'isBase64Encoded'字段,所以我很抱歉您必须让API Gateway代替Express来管理它,以使其正常工作。

另外,Jimp提供了一个getBufferAsync方法,它返回一个promise,所以你可以直接await它,使代码稍微简单一些。

希望能对你有所帮助!

编辑:

我仍然在尝试使用Express使其工作,所以我找到了这个:https://github.com/awslabs/aws-serverless-express/issues/99#issuecomment-332169739

我必须承认我没有测试过,但如果您确实需要Express为您处理路由,则可能会起作用。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接