Using signed requests with AWS S3 and uploading photos?

冷暖自知 提交于 2021-01-28 05:36:37

问题


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

I went with getSignedUrl route.

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) the link makes me download the file instead of displaying it in browser.

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

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.

Client Side calls to server

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))
    })
  }

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;
      });
    });

回答1:


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.



来源:https://stackoverflow.com/questions/47148168/using-signed-requests-with-aws-s3-and-uploading-photos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!