【问题标题】:Downloading images form AWS S3 via Lambda and API Gateway--using fetch class通过 Lambda 和 API Gateway 从 AWS S3 下载图像——使用 fetch 类
【发布时间】:2018-09-15 03:58:28
【问题描述】:

我正在尝试使用JavaScript fetch APIAWS API GatewayAWS LambdaAWS 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 中:

【问题讨论】:

    标签: amazon-s3 aws-lambda aws-api-gateway fetch-api claudiajs


    【解决方案1】:

    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;
    

    【讨论】:

      猜你喜欢
      • 2020-03-23
      • 2020-07-24
      • 2018-11-09
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 2015-10-15
      相关资源
      最近更新 更多