Amazon s3 将base64字符串保存到Amazon S3

Amazon s3 将base64字符串保存到Amazon S3,amazon-s3,base64,react-native,Amazon S3,Base64,React Native,我正在开发一个React本机应用程序,其中我尝试从用户的相机卷中拍摄图像,将其转换为base64字符串,并将其存储到AmazonS3以供以后使用 在这篇博文之后,我能够拍摄用户的相机胶卷并将图像转换为base64: 然后,我将base64字符串图像数据发送到一个简单的Express服务器,我已经设置好将数据发布到我的AmazonS3存储桶中 // Only getting first img in camera roll for testing purposes CameraRoll.getP

我正在开发一个React本机应用程序,其中我尝试从用户的相机卷中拍摄图像,将其转换为base64字符串,并将其存储到AmazonS3以供以后使用

在这篇博文之后,我能够拍摄用户的相机胶卷并将图像转换为base64:

然后,我将base64字符串图像数据发送到一个简单的Express服务器,我已经设置好将数据发布到我的AmazonS3存储桶中

// Only getting first img in camera roll for testing purposes
CameraRoll.getPhotos({first: 1}).then((data) => {

  for (let i = 0; i < data.edges.length; i++) {
    NativeModules.ReadImageData.readImage(data.edges[i].node.image.uri, (imageBase64) => {

      // Does the string have to be encoded?
      // const encodeBase64data = encodeURIComponent(imageBase64);

      const obj = {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          'img': imageBase64
        })
      }

      fetch('http://localhost:3000/saveImg', obj)
        .then((res) => {
          console.log(JSON.parse(res._bodyInit));
        })

    })
  }
我成功地将数据发送到Amazon S3并在bucket中查看我的图像文件,但是当我尝试访问链接以查看实际图像本身,或者将其拉入我的React原生应用程序时,我什么也得不到

ie如果我在Amazon S3中访问上面的
test\u img
url,我会得到:

https://s3.amazonaws.com/my_bucket_name/test_img
This XML file does not appear to have any style information associated with    it. The document tree is shown below.
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>BCE6E07705CF61B0</RequestId>
    <HostId>
aF2l+ucPPHRog1QaaXjEahZePF0A9ixKR0OTzlogWFHYXHUMUeOf2uP7D/wtn7hu3bLWG8ulKO0=

     </HostId>
</Error>
我已经手动将图像上传到同一个bucket中,它们的链接看起来很好,另外,我还可以将它们拉到我的React本机应用程序中,查看起来没有问题

我的问题是,在获取base64字符串数据和将其发送到Express服务器以保存到bucket之间,我做错了什么? base64字符串是否必须编码? 在将base64字符串发送到Express之前,是否需要将其转换为Blob


谢谢你的帮助

这是一个权限问题,与ReactNative和Base64编码无关

您有一个“AccessDenied”-错误,这意味着该映像不可公开使用。只有当您使用正确的权限配置bucket(甚至是特定的文件,我将在下面解释),您才能在没有签名URL的情况下接收图像内容

要调查这是否是根本原因,您可以尝试在s3控制台中公开映像。只需转到并在图像文件上单击鼠标右键:

上下文菜单中列出了两个您感兴趣的项目:“公开”和“打开”

如果选择“打开”,您将获得文件的“签名url”,这意味着图像的普通url将显示特定参数,以使此文件在一段时间内公开:

此外,您还可以尝试“公开”并再次重新加载您的图像url,看看它现在是否对您可用

1。进近,桶宽:

一种解决方案是为整个bucket创建IAM策略,以使其中的每个对象公开:

{
  "Version": "2008-10-17",
  "Statement": [{
    "Sid": "AllowPublicRead",
    "Effect": "Allow",
    "Principal": {
      "AWS": "*"
    },
    "Action": [ "s3:GetObject" ],
    "Resource": [ "arn:aws:s3:::YOUR_BUCKET_NAME/*" ]
  }]
}
因此,在AWS控制台中转到您的bucket,单击该bucket,然后在右侧窗格中打开“permissions”。您可以创建一个与上面类似的新策略

2。第二种解决方案,特定对象

另一种方法是在putObject方法中添加:

'ACL'          => 'public-read'
我不知道您的后端sdk,但我猜是这样的:

var data = {
    Key: test_img,
    Body: req.body.img,
    ContentEncoding: 'base64',
    ContentType: 'image/png',
    ACL: 'public-read',
  };
我刚刚在这里添加了ACL特定的行。
根据SDK的不同,可能需要使用普通aws标题“x-amz-acl:public read”而不是“acl:public read”。两者都试试。

将Bucket策略添加到您的Bucket将解决问题。

我刚刚遇到了相同的问题。在上传到S3之前,必须将base64字符串转换为Blob

说明如何进行此转换。使用,以下是如何在您的示例中集成:

require('node-fetch')

app.post('/saveImg', function(req, res) {

  // this will be moved once testing is complete
  var s3Bucket = new AWS.S3( { params: {Bucket: '[my_bucket_name]'} } );

  var imageUri = 'data:image/png;base64,' + req.body.img;

  fetch(imageUri)
    .then(function(res){ return res.blob() })
    .then(function(image){
      var data = {
        Key: test_img,
        Body: image,
        ContentEncoding: 'base64',
        ContentType: 'image/png'
      };

      s3Bucket.putObject(data, function(err, data){
       if (err) {
         console.log(err);
         console.log('Error uploading data: ', data);
       } else {
         res.send(data);
         console.log('successfully uploaded the image!');
       }
     });
   })
});

完成后,您可以在S3上预览上传的图像,或将其拉入您的应用程序。

订阅时,我需要此解决方案。不幸的是,此解决方案不适用于我。我为我的bucket添加了IAM策略,当我尝试从各自的URL加载从相机卷保存的图像时,我只看到页面左上角出现了一个白色的小方框。我确保我的桶里的图片也是公开的,我仍然收到同样的问题。只有作为base64字符串从我的相机卷加载的图像没有像我手动上传的那个样工作,因为测试看起来很好。
require('node-fetch')

app.post('/saveImg', function(req, res) {

  // this will be moved once testing is complete
  var s3Bucket = new AWS.S3( { params: {Bucket: '[my_bucket_name]'} } );

  var imageUri = 'data:image/png;base64,' + req.body.img;

  fetch(imageUri)
    .then(function(res){ return res.blob() })
    .then(function(image){
      var data = {
        Key: test_img,
        Body: image,
        ContentEncoding: 'base64',
        ContentType: 'image/png'
      };

      s3Bucket.putObject(data, function(err, data){
       if (err) {
         console.log(err);
         console.log('Error uploading data: ', data);
       } else {
         res.send(data);
         console.log('successfully uploaded the image!');
       }
     });
   })
});