在AWS S3上使用签名的请求并上传照片? [英] Using signed requests with AWS S3 and uploading photos?

查看:145
本文介绍了在AWS S3上使用签名的请求并上传照片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个反应很简单的本机应用程序,我正在尝试将图像上传到s3.

So I have a react native application that's kind of like slack and I'm trying to do image uploads to s3.

我选择了getSignedUrl路由.

I went with getSignedUrl route.

所以客户拍了张照片,将已签名的url提取到存储桶中然后更改该用户在服务器上的网址然后对已获取的签名网址进行放置请求.

So the client pics a photo, fetches a signed url to the bucket then changes the url on the server for that user then a put request to the signed url that was fetched.

大多数情况下,文件存放在正确的存储桶中,它们是照片.但是

It mostly works the files get in the right bucket and they are photos. but

A)链接使我可以下载文件,而不是在浏览器中显示它.

A) the link makes me download the file instead of displaying it in browser.

B)该文件不是图像...它是xml文件,只能在photoshop中打开

B) the file isn't an image...its an xml file and can only be opened in photoshop

我尝试更改data.append类型中的类型,将标头添加到已签名的请求中将x-amz-标头添加到已签名的请求在服务器中对文件类型进行硬编码使用本机模块将图像转换为base64字符串,但仍然出错.

I've tried changing the type in the data.append type, Adding header to the signed request Adding x-amz- headers to the signed request hard coding the file type in server converting image to base64 string with a native module but It still is coming up wrong.

客户端到服务器的呼叫

uploadToServer() {

    // alert('coming soon!');

    //Go back to profile page
    this.props.navigation.goBack();

    //grab user from navigator params
    let user = this.props.navigation.state.params.user
    let pic = this.state.selected;

    // turn uri into base64
    NativeModules.ReadImageData.readImage(pic.uri, (image) => {
      console.log(image);

      var data = new FormData();
      data.append('picture', {
        uri: image,
        name: pic.filename,
        type: 'image/jpeg'
      });

      //get the signed Url for uploading
      axios.post(api.getPhotoUrl, {fileName: `${pic.filename}`}).then((res) => {

        console.log("get Photo URL response", res);

        //update the user with the new url
        axios.patch(api.fetchUserByID(user.id), {profileUrl: res.data.url}).then((resp) => {

          console.log("Update User response", resp.data);
        }).catch(err => errorHandler(err));

        //upload the photo using the signed request url given to me.
        //DO I NEED TO TURN DATA INTO A BLOB?
        fetch(res.data.signedRequest, {
          method: 'PUT',
          body: data
        }).then((response) => {
          console.log("UPLOAD PHOTO RESPONSE: ", response);
        }).catch(err => errorHandler(err))
      }).catch((err) => errorHandler(err))
    })
  }

从头到尾获取签名的URL逻辑

GET SIGNED URL logic from on out

router.post('/users/sign-s3', (req, res) => {
      const s3 = new aws.S3({signatureVersion: 'v4', region: 'us-east-2'});
      const fileName = `${req.user.id}-${req.body.fileName}`;
      const fileType = req.body.fileType;
      const s3Params = {
        Bucket: AWS_S3_BUCKET,
        Key: `images/${fileName}`,
        Expires: 60,
        ContentType: 'image/jpeg',
        ACL: 'public-read'
      };

      s3.getSignedUrl('putObject', s3Params, (err, data) => {
        if (err) {
          console.log(err);
          return res.end();
        }
        const returnData = {
          signedRequest: data,
          url: `https://${AWS_S3_BUCKET}.s3.amazonaws.com/${s3Params.Key}`
        };
        res.write(JSON.stringify(returnData));
        res.end();
        return null;
      });
    });

推荐答案

如果要将内容类型显示在浏览器中,则需要将图像的内容类型从图像更改为支持的xml格式.

You need to change content type from image to supported xml format if you want it to be displayed in browser.

请参考并相应地设置内容类型.

Refer this and set content type accordingly.

这篇关于在AWS S3上使用签名的请求并上传照片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆