使用AWS S3签名请求并上传照片?

时间:2017-11-07 00:40:26

标签: javascript amazon-web-services react-native amazon-s3

所以我有一个反应原生的应用程序,有点像松弛,我试图将图像上传到s3。

我选择了getSignedUrl路线。

所以客户拍照片, 获取已签名的URL到存储桶 然后更改该用户的服务器上的URL 然后对已获取的已签名网址发出请求。

它主要用于将文件放入正确的存储桶中,它们是照片。但是

A)链接让我下载文件而不是在浏览器中显示它。

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

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

客户端调用服务器

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逻辑

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 个答案:

答案 0 :(得分:1)

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

Refer this并相应地设置内容类型。