使用 AWS Amplify 从 React Native 上传到 S3
Upload to S3 from React Native with AWS Amplify
我正在尝试使用 Amplify 从 React Native 将图像上传到 S3。我能够成功上传文本文件。但不是图像。
这是我的代码:
import React from 'react';
import {View, Text, Button, Image} from 'react-native';
import {identityPoolId, region, bucket} from '../auth';
import image from '../assets/background.png';
import Amplify, {Storage} from 'aws-amplify';
Amplify.configure({
Auth: {identityPoolId,region},
Storage : {bucket,region}
})
const upload = () => {
Storage.put('logo.jpg', image, {contentType: 'image/jpeg'})
.then(result => console.log('result from successful upload: ', result))
.catch(err => console.log('error uploading to s3:', err));
}
const get = () => { //this works for both putting and getting a text file
Storage.get('amir.txt')
.then(res => console.log('result get', res))
.catch(err => console.log('err getting', err))
}
export default function ImageUpload(props) {
return (
<View style={{alignItems : 'center'}}>
<Image style={{width: 100, height: 100}} source={image} />
<Text>Click button to upload above image to S3</Text>
<Button title="Upload to S3" onPress={upload}/>
<Button title="Get from S3" onPress={get}/>
</View>
)
}
错误信息是:
error uploading to s3: [Error: Unsupported body payload number]
在我们最近的 React 单页应用程序 (SPA) 样式 Web 应用程序中,我们使用 "S3 Signed URLs" 来高效 upload/download 文件,我认为与直接upload/download.
后端服务是在什么地方实现的?
您可以在您的节点服务器上执行此操作,将其保存在 URL 中并将其发送回应用程序。
它看起来像:
const AWS = require('aws-sdk');
var s3 = new AWS.S3({accessKeyId:'XXXXXXXXXXXX', secretAccessKey:'YYYYYYYYYYYY', region:'REGION'});
var params = {Bucket: 'yourBucket', Key: 'your_image/your_image.jpg', ContentType: 'image/jpeg'};
s3.getSignedUrl('putObject', params, function (err, url) {
// send it back to the app
});
在应用程序方面,您将拥有类似的内容:
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
Alert.aler("Upload", "Done");
} else {
Alert.aler("Upload", "Failed");
}
}
}
xhr.open('PUT', presignedUrlReceiveFromServer)
xhr.setRequestHeader('Content-Type', fileType)
xhr.send({ uri: imageFilePath, type: fileType, name: imageFileName })
希望对您有所帮助
我最终使用 react-native-aws3 库将图像上传到 S3。
我希望能更直接地找到有关如何使用 AWS amplify 直接上传图像的答案,但它没有用。所以这就是我所做的:
(此函数的包装器是一个 React 组件。我正在使用 'expo-image-picker' 的 ImagePicker、'expo-permissions' 的权限和 'expo-constants' 的常量来设置从相册)
import {identityPoolId, region, bucket, accessKey, secretKey} from '../auth';
import { RNS3 } from 'react-native-aws3';
async function s3Upload(uri) {
const file = {
uri,
name : uri.match(/.{12}.jpg/)[0],
type : "image/png"
};
const options = { keyPrefix: "public/", bucket, region,
accessKey, secretKey, successActionStatus: 201}
RNS3.put(file, options)
.progress(event => {
console.log(`percentage uploaded: ${event.percent}`);
})
.then(res => {
if (res.status === 201) {
console.log('response from successful upload to s3:',
res.body);
console.log('S3 URL', res.body.postResponse.location);
setPic(res.body.postResponse.location);
} else {
console.log('error status code: ', res.status);
}
})
.catch(err => {
console.log('error uploading to s3', err)
})
}
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes : ImagePicker.MediaTypeOptions.All,
allowsEditing : true,
aspect : [4,3],
quality : 1
});
console.log('image picker result', result);
if (!result.cancelled) {
setImage(result.uri);
s3Upload(result.uri);
}
}
我正在尝试使用 Amplify 从 React Native 将图像上传到 S3。我能够成功上传文本文件。但不是图像。
这是我的代码:
import React from 'react';
import {View, Text, Button, Image} from 'react-native';
import {identityPoolId, region, bucket} from '../auth';
import image from '../assets/background.png';
import Amplify, {Storage} from 'aws-amplify';
Amplify.configure({
Auth: {identityPoolId,region},
Storage : {bucket,region}
})
const upload = () => {
Storage.put('logo.jpg', image, {contentType: 'image/jpeg'})
.then(result => console.log('result from successful upload: ', result))
.catch(err => console.log('error uploading to s3:', err));
}
const get = () => { //this works for both putting and getting a text file
Storage.get('amir.txt')
.then(res => console.log('result get', res))
.catch(err => console.log('err getting', err))
}
export default function ImageUpload(props) {
return (
<View style={{alignItems : 'center'}}>
<Image style={{width: 100, height: 100}} source={image} />
<Text>Click button to upload above image to S3</Text>
<Button title="Upload to S3" onPress={upload}/>
<Button title="Get from S3" onPress={get}/>
</View>
)
}
错误信息是:
error uploading to s3: [Error: Unsupported body payload number]
在我们最近的 React 单页应用程序 (SPA) 样式 Web 应用程序中,我们使用 "S3 Signed URLs" 来高效 upload/download 文件,我认为与直接upload/download.
后端服务是在什么地方实现的?
您可以在您的节点服务器上执行此操作,将其保存在 URL 中并将其发送回应用程序。 它看起来像:
const AWS = require('aws-sdk');
var s3 = new AWS.S3({accessKeyId:'XXXXXXXXXXXX', secretAccessKey:'YYYYYYYYYYYY', region:'REGION'});
var params = {Bucket: 'yourBucket', Key: 'your_image/your_image.jpg', ContentType: 'image/jpeg'};
s3.getSignedUrl('putObject', params, function (err, url) {
// send it back to the app
});
在应用程序方面,您将拥有类似的内容:
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
Alert.aler("Upload", "Done");
} else {
Alert.aler("Upload", "Failed");
}
}
}
xhr.open('PUT', presignedUrlReceiveFromServer)
xhr.setRequestHeader('Content-Type', fileType)
xhr.send({ uri: imageFilePath, type: fileType, name: imageFileName })
希望对您有所帮助
我最终使用 react-native-aws3 库将图像上传到 S3。 我希望能更直接地找到有关如何使用 AWS amplify 直接上传图像的答案,但它没有用。所以这就是我所做的:
(此函数的包装器是一个 React 组件。我正在使用 'expo-image-picker' 的 ImagePicker、'expo-permissions' 的权限和 'expo-constants' 的常量来设置从相册)
import {identityPoolId, region, bucket, accessKey, secretKey} from '../auth';
import { RNS3 } from 'react-native-aws3';
async function s3Upload(uri) {
const file = {
uri,
name : uri.match(/.{12}.jpg/)[0],
type : "image/png"
};
const options = { keyPrefix: "public/", bucket, region,
accessKey, secretKey, successActionStatus: 201}
RNS3.put(file, options)
.progress(event => {
console.log(`percentage uploaded: ${event.percent}`);
})
.then(res => {
if (res.status === 201) {
console.log('response from successful upload to s3:',
res.body);
console.log('S3 URL', res.body.postResponse.location);
setPic(res.body.postResponse.location);
} else {
console.log('error status code: ', res.status);
}
})
.catch(err => {
console.log('error uploading to s3', err)
})
}
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes : ImagePicker.MediaTypeOptions.All,
allowsEditing : true,
aspect : [4,3],
quality : 1
});
console.log('image picker result', result);
if (!result.cancelled) {
setImage(result.uri);
s3Upload(result.uri);
}
}