React Native 在浏览器上打开上传的图像AWS S3 URL时被拒绝

unguejic  于 6个月前  发布在  React
关注(0)|答案(2)|浏览(48)

我正在使用React Native将图像上传到AWS S3。我已经成功上传,但其URL被拒绝,然后粘贴到浏览器中。
我已经尝试了许多格式的URL和s3.getSignedUrl(但我得到了其他错误:NoSuckKey,SignatureDoesNotMatch)
第一个月

const uploadImageToS3 = async () => {
    try {
      const response = await fetch(photo);
      const blob = await response.blob();

      // Upload the image directly to S3 with public-read ACL
      const result = await Storage.put(uuid.v4(), blob, {
        contentType: 'image/jpeg',
        level: 'public',
        bucket: BUCKET_NAME,
      });

      console.log('Image uploaded successfully', result.key);

      const s3Link = `https://${BUCKET_NAME}.s3.ap-southeast-1.amazonaws.com/${result.key}`;
      console.log('JSON: ', s3Link);
    } catch (error) {
      console.log('ERROR UPLOADING FILE: ', error);
    }
  };

字符串
Others way I've tried with S3.getSignedUrl

const pathToImageFile = async () => {
    try {
      const response = await fetch(photo);
      const blob = await response.blob();
      const result = await Storage.put(uuid.v4(), blob, {
        contentType: 'image/jpeg',
        level: 'public',
        bucket: BUCKET_NAME,
      });
      console.log('Image uploaded successfully', result.key);

      const params = {
        Bucket: BUCKET_NAME,
        Key: `${result.key}.jpeg`,
        Expires: 60 * 60 * 24 * 7,
      };

      const url = await s3.getSignedUrl('getObject', params);
      console.log('URL: ', url);

      // parseUrl(`https://${bucket}.s3.${region}.amazonaws.com/${Key}`)
      const s3Link = `https://${BUCKET_NAME}.s3.ap-southeast-1.amazonaws.com/${result.key}`;
      console.log('JSON: ', s3Link);
    } catch (error) {
      console.log('ERROR UPLOADING FILE: ', error);
    }
  };


S3

const credentials = new AWS.Credentials({
    accessKeyId: ACCESS_KEY_ID,
    secretAccessKey: SECRET_ACCESS_KEY,
    Bucket: BUCKET_NAME,
  });

  const s3 = new S3({
    signatureVersion: 'v4',
    region: 'ap-southeast-1',
    credentials,
  });


My full code

import {StyleSheet, Text, View, TouchableOpacity, Image} from 'react-native';
import React, {useEffect, useState, useRef} from 'react';
import {Camera} from 'react-native-vision-camera';
import uuid from 'react-native-uuid';
import {Storage} from 'aws-amplify';
import {BUCKET_NAME, MY_BUCKET_URL} from '../utils/contanst';
import {S3} from 'aws-sdk';
import {ACCESS_KEY_ID, SECRET_ACCESS_KEY} from '../PrivateKey';

const VisionCamera = () => {
  const cameraPermission = Camera.requestCameraPermission();
  useEffect(() => {
    cameraPermission.then(res => {
      console.log(res);
    });
  }, []);

  const credentials = new AWS.Credentials({
    accessKeyId: ACCESS_KEY_ID,
    secretAccessKey: SECRET_ACCESS_KEY,
    Bucket: BUCKET_NAME,
  });

  const s3 = new S3({
    signatureVersion: 'v4',
    region: 'ap-southeast-1',
    credentials,
  });

  const devices = Camera.getAvailableCameraDevices();
  const device = devices.find(d => d.position === 'back');

  const camera = useRef(null);
  const [isTakingPhoto, setIsTakingPhoto] = useState(false);
  const [photo, setPhoto] = useState(null);

  const takingPhoto = async () => {
    if (camera.current == null) return;
    const photo = await camera.current.takePhoto();
    console.log('photo', `file://${photo.path}`);
    setPhoto(`file://${photo.path}`);
    setIsTakingPhoto(false);
  };

  const pathToImageFile = async () => {
    try {
      const response = await fetch(photo);
      const blob = await response.blob();
      const result = await Storage.put(uuid.v4(), blob, {
        contentType: 'image/jpeg',
        level: 'public',
        bucket: BUCKET_NAME,
      });
      console.log('Image uploaded successfully', result.key);

      const params = {
        Bucket: BUCKET_NAME,
        Key: `${result.key}.jpeg`,
        Expires: 60 * 60 * 24 * 7,
      };

      const url = await s3.getSignedUrl('getObject', params);
      console.log('URL: ', url);

      // parseUrl(`https://${bucket}.s3.${region}.amazonaws.com/${Key}`)
      const s3Link = `https://${BUCKET_NAME}.s3.ap-southeast-1.amazonaws.com/${result.key}`;
      console.log('JSON: ', s3Link);
    } catch (error) {
      console.log('ERROR UPLOADING FILE: ', error);
    }
  };

  if (device == null) return <NoCameraDeviceError />;
  return (
    <>
      {isTakingPhoto ? (
        <>
          <Camera
            style={StyleSheet.absoluteFill}
            device={device}
            isActive={true}
            photo={true}
            ref={camera}
          />
          <TouchableOpacity
            style={styles.btnTakingPhoto}
            onPress={() => takingPhoto()}>
            <Text>Take Photo</Text>
          </TouchableOpacity>
        </>
      ) : (
        <>
          <View style={{flex: 1}}>
            <TouchableOpacity onPress={() => setIsTakingPhoto(true)}>
              <Text>Taking Photo</Text>
            </TouchableOpacity>
            <Image source={{uri: photo}} style={styles.image} />
            <TouchableOpacity onPress={() => pathToImageFile()}>
              <Text>Upload Photo</Text>
            </TouchableOpacity>
          </View>
        </>
      )}
    </>
  );
};

export default VisionCamera;

const styles = StyleSheet.create({
  btnTakingPhoto: {
    position: 'absolute',
    bottom: 0,
    width: '100%',
    height: 50,
    backgroundColor: 'red',
    justifyContent: 'center',
    alignItems: 'center',
  },
  image: {
    width: 200,
    height: 200,
    alignSelf: 'center',
    resizeMode: 'contain',
  },
});

Here my policies of IAM AWS

List Policies
JSON Script

kpbpu008

kpbpu0081#

上传后我放弃了获取URL。
然后,我试图通过提供图像的关键字来获取URL,它工作了。

const getImageUrlByKey = async () => {
imageKey = 'MY_IMAGE_KEY';
try {
  const url = await Storage.get(imageKey, {
    level: 'public',
    bucket: BUCKET_NAME,
  });
  console.log('URL for', imageKey, ':', url)

  // return url;
} catch (error) {
  console.log('ERROR GETTING IMAGE URL: ', error);
  return null;
}

字符串
};

v9tzhpje

v9tzhpje2#

OMG它工作了,我必须将策略脚本更改为permissions tab of bucket not into IAM Polic

相关问题