当前位置: 首页 > 知识库问答 >
问题:

通过Lambda和API网关从AWS S3下载图像——使用fetch类

梁丘伟
2023-03-14

我正在尝试使用JavaScript fetch API、AWS API Gateway、AWS Lambda和AWS S3创建一个允许用户上传和下载媒体的服务。服务器使用NodeJs 8.10;浏览器为Google Chrome版本69.0.3497.92(官方版本)(64位)。

从长远来看,允许的媒体包括音频、视频和图像。现在,我很高兴能让这些图片发挥作用。

我遇到的问题:我的浏览器端客户端,使用fetch实现,能够通过API Gateway和Lambda很好地将JPEG上传到S3。我可以使用curl或S3控制台从我的S3存储桶下载JPEG,然后在图像查看器中查看图像。

但是,如果我尝试通过浏览器端客户端下载图像并获取,我将无法在浏览器中显示任何内容。

这是来自浏览器端客户端的代码:

fetch(
  'path/to/resource',
  {
    method: 'post',
    mode: "cors",
    body: an_instance_of_file_from_an_html_file_input_tag,
    headers: {
      Authorization: user_credentials,
      'Content-Type': 'image/jpeg',
    },
  }
).then((response) => {
  return response.blob();
}).then((blob) => {
  const img = new Image();
  img.src = URL.createObjectURL(blob);
  document.body.appendChild(img);
}).catch((error) => {
  console.error('upload failed',error);
});

这是服务器端代码,使用Claudia.js:

const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();

api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
  providerARNs: ['arn of my cognito user pool']
});

api.get(
  '/media',
  (request) => {
    'use strict';

    const s3 = new AWS.S3();
    const params = {
      Bucket: 'name of my bucket', 
      Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
    };
    return s3.getObject(params).promise().then((response) => {
       return response.Body;
     })
    ;
  }
);

module.exports = api;

以下是Chrome网络面板中的初始OPTION请求和响应标头:

下面是随后的GET请求和响应头:

我感兴趣的是,在S3控制台中,图像大小报告为699873(没有单位),但GET事务的响应体在Chrome中报告为大约2.5 MB(同样,没有单位)。

生成的图像是一个16x16正方形的死链接。我在浏览器的控制台或CloudWatch中没有收到任何错误或警告。

我尝试了很多事情;我很想听听外面的任何人都能想到什么。

提前谢谢。

编辑:在Chrome:

共有1个答案

公冶嘉
2023-03-14

Claudia要求客户端指定它将在二进制有效负载上接受哪种MIME类型。因此,将'Content-type'配置保留在Headers对象客户端:

fetch(
  'path/to/resource',
  {
    method: 'post',
    mode: "cors",
    body: an_instance_of_file_from_an_html_file_input_tag,
    headers: {
      Authorization: user_credentials,
      'Content-Type': 'image/jpeg', // <-- This is important.
    },
  }
).then((response) => {
  return response.blob();
}).then((blob) => {
  const img = new Image();
  img.src = URL.createObjectURL(blob);
  document.body.appendChild(img);
}).catch((error) => {
  console.error('upload failed',error);
});

然后,在服务器端,您需要告诉Claudia响应应该是二进制的,并使用哪种MIME类型:

const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();

api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
  providerARNs: ['arn of my cognito user pool']
});

api.get(
  '/media',
  (request) => {
    'use strict';

    const s3 = new AWS.S3();
    const params = {
      Bucket: 'name of my bucket', 
      Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
    };
    return s3.getObject(params).promise().then((response) => {
       return response.Body;
     })
    ;
  },
  /** Add this. **/
  {
    success: { 
      contentType: 'image/jpeg', 
      contentHandling: 'CONVERT_TO_BINARY', 
    }, 
  }
);

module.exports = api;
 类似资料:
  • 问题内容: 我需要使用Python从网站上检索图像。但是,该图像不是链接文件的形式,而是GIF数据URI。如何下载此文件并将其存储在.gif文件中? 问题答案: 这应该使您朝正确的方向前进。 首先,假设您已检索到图像uri数据,并将其保存在名为img_data的python变量中: 现在,您需要解码来自base64的图片并将其保存到文件中:

  • 我有一个这样的设置: 浏览器->API网关->lambda:87 ms 如何快速调用Lambda函数?

  • 我需要从endpoint获取一些数据,然后根据响应将这些数据存储到数据库中。

  • 我目前在lambda函数和API网关方面遇到了问题。我已经在API网关中启用了代理集成,以便返回Lambda函数的状态代码。现在我有一个问题,调用根本没有执行。错误图片 如果我测试Lambda,一切正常,数据库中的条目将被执行。不通过API网关。 我有什么问题? 非常感谢你的帮助! 测验 编辑: 我将此作为IAM政策添加: 但它仍然带来这个错误:

  • 我想知道是否可以使用API网关POST方法将YAML有效负载格式传递给AWS Lambda函数。我不想要任何有效载荷的模型,也不想使用模板检查有效载荷。我只想以YAML格式将数据传递给Lambda。有人成功地做到了这一点吗? 我之前使用JSON有效负载将有效负载传递给Lambda,但由于某些设计问题,我觉得YAML格式的有效负载更适合此任务。我尝试在请求正文中传递YAML有效负载,但出现以下错误。

  • 我有一个lambda,它需要通过api网关(使用lambda集成)返回一个二进制对象和一些http头(例如,内容类型),或者重定向到另一个URL。在二进制支持示例中(例如。https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/)lambda只返回二进制对象(图