React-native 上传图片到 amazon s3
Posted
技术标签:
【中文标题】React-native 上传图片到 amazon s3【英文标题】:React-native upload image to amazons s3 【发布时间】:2015-08-24 13:51:00 【问题描述】:我想将图像从我的应用上传到 S3 服务器。我计算了所有数据和代码(在计算机上使用 curl 测试),但我无法弄清楚如何正确调用“获取”。我得到了回应:
'您指定的前提条件中至少有一个不成立。条件:bucket POST 必须是enclosure-type-multipart/form-data'
如何在 react-natives fetch 中重新创建表单数据?没有我可以附加的 FormData,然后像 fetches 示例中那样发送它。
编辑: 感谢@philipp-von-weitershausen,感谢您添加了此功能。但是我在调用它时遇到了一些麻烦。我得到“不支持的 BodyInit 类型”。发现是因为在 fetch.js: "support.formData" 返回 false。当我调用 fetch 时,我错过了什么?
我的代码示例:
var form = new FormData();
form.append("FormData", true)
form.append("name", this.state.invoiceNumber)
form.append("key", this.state.invoiceNumber)
form.append("Content-Type", "image/png")
form.append('file', this.props.uri)
//alert(FormData.prototype.isPrototypeOf(form))
fetch(amazon_url,body: form,mode: "FormData", method: "post", headers: "Content-Type": "multipart/FormData")
.then((response) => response.json())
.catch((error) =>
alert("ERROR " + error)
)
.then((responseData) =>
alert("Succes "+ responseData)
)
.done();
【问题讨论】:
您有最终工作代码的示例吗?我也遇到了麻烦。 事实上,你有没有一个例子可以发布表单变量(没有图像 - 看到下一个 RN 构建添加图像支持)。 react-native-fetch-blob 可以为您做到这一点。 【参考方案1】:multipart/form-data
对混合有效负载(JS 字符串 + 图像有效负载)的 React Native(通过 XHR FormData
API)的支持正在开发中。它应该很快就会登陆 GitHub。
【讨论】:
aaa 它登陆了:github.com/facebook/react-native/commit/… 太棒了!!我看到你也改变了调用 fetch 的方法?它停止工作或显示错误:Undiefiened 不是函数(评估 RCTDataMenager.queryData('http', methode: method, url: url, data: data, headers: headers )。任何机会快速提示发生了什么变化? 没关系,我有两个版本的 react-native 并且在这个文件夹中彼此不喜欢......【参考方案2】:有人问,所以我发布了我是如何做到的。它很久以前就安静地完成了,所以如果你有任何 cmets 或者做得真的很糟糕,我愿意接受批评;) 照片从 cameraRoll 中读取并存储在 'latestPhoto' 中。
上传照片到 S3 服务器:
第一步:生成数据:
_addTextParam()
var textParams = this.state.textParams;
s3_upload_id = this.makeid()
textParams.push( name: "key", value: this.state.upload_path + s3_upload_id + '/' + this.state.att_name + ".jpg" )
textParams.push( name: "AWSAccessKeyId", value: this.state.key )
textParams.push( name: "acl", value: "public-read" )
textParams.push( name: "success_action_status", value: "201" )
textParams.push( name: "policy", value: this.state.policy )
textParams.push( name: "signature", value: this.state.signature )
textParams.push( name: "Content-Type", value: "image/jpeg" )
this.setState( textParams: textParams );
第 2 步:发送数据:
_send()
this._addTextParam()
var xhr = new XMLHttpRequest();
xhr.open('POST', "http://" + this.state.fs_domain + "." + this.state.server);
xhr.onload = () =>
this.setState( isUploading: false );
if (xhr.status !== 201)
Alertios.alert(
'Upload failed',
'Expected HTTP 200 OK response, got ' + xhr.status + "/" + xhr.responseText
);
return;
if (!xhr.responseText)
AlertIOS.alert(
'Upload failed',
'No response payload.'
);
return;
var index = xhr.responseText.indexOf( "http://" + this.state.fs_domain + "." + this.state.server);
if (index === -1)
AlertIOS.alert(
'Upload failed',
'Invalid response payload.'
);
return;
var url = xhr.responseText.slice(index).split('\n')[0];
this.state.s3_file_id = xhr.responseText.split('Tag>"')[1].split('"')[0]
this.state.s3_file_path = xhr.responseText.split('Location>')[1].split('<')[0]
this.setState( isUploading: false );
RCTDeviceEventEmitter.emit('Uploaded')
;
var formdata = new FormData();
this.state.textParams.forEach((param) =>
formdata.append(param.name, param.value)
);
formdata.append('file', ...this.state.latestPhoto, name: (this.state.att_name+".jpg") );
xhr.send(formdata);
this.setState( isUploading: true );
,
【讨论】:
您是如何生成签名的?我在网上找到的所有模块都依赖于一些节点功能,例如http
和 fs
。
@HarryMoreno 照片由:CameraRoll 加载,我从我们用 Ruby on Rails 编写的主应用程序获取签名。但我认为您可以根据 AWS 文档重新创建它。【参考方案3】:
@Michał Zubrzycki 谢谢,您上传图片的代码对我有用,只需稍作改动。
const photo =
uri: user.profilePicture,
type: "image/jpeg",
name: "photo.jpg"
;
const form = new FormData();
form.append("ProfilePicture", photo);
fetch(Constants.API_USER + "me/profilePicture",
body: form,
method: "PUT",
headers:
"Content-Type": "multipart/form-data",
Authorization: "Bearer " + user.token
)
.then(response => response.json())
.catch(error =>
console.log("ERROR ", error);
)
.then(responseData =>
console.log("Success", responseData);
)
.done();
【讨论】:
【参考方案4】:S3 选项:
// this.state.s3options in YourComponent
"url": "https://yourapp.s3.eu-central-1.amazonaws.com",
"fields":
"key": "cache/22d65141b48c5c44eaf93a0f6b0abc30.jpeg",
"policy": "eyJleHBpcm...1VDE0Mzc1OVoifV19",
"x-amz-credential": "AK...25/eu-central-1/s3/aws4_request",
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-date": "20161125T143759Z",
"x-amz-signature": "87863c360...b9b304bfe650"
组件:
class YourComponent extends Component
// ...
// fileSource looks like: uri: "content://media/external/images/media/13", isStatic: true
async uploadFileToS3(fileSource)
try
var formData = new FormData();
// Prepare the formData by the S3 options
Object.keys(this.state.s3options.fields).forEach((key) =>
formData.append(key, this.state.s3options.fields[key]);
);
formData.append('file',
uri: fileSource.uri,
type: 'image/jpeg',
);
formData.append('Content-Type', 'image/jpeg')
var request = new XMLHttpRequest();
request.onload = function(e)
if (e.target.status === 204)
// Result in e.target.responseHeaders.Location
this.setState(avatarSourceRemote: uri: e.target.responseHeaders.Location)
.bind(this)
request.open('POST', this.state.s3options.url, true);
request.setRequestHeader('Content-type', 'multipart/form-data');
request.send(formData);
catch(error)
console.error(error);
// Example display the uploaded image
render()
if (this.state.avatarSourceRemote)
return (
<Image source=this.state.avatarSourceRemote style=width: 100, height: 100 />
);
else
return (
<Text>No Image</Text>
);
【讨论】:
【参考方案5】://You need to Initialize Amplify in App.js
import Amplify from 'aws-amplify';
Amplify.configure(
Auth:
identityPoolId: Config.AWS_COGNITO_IDENTITY_POOL_ID, //REQUIRED - Amazon Cognito Identity Pool ID
region: Config.S3_REGION, // REQUIRED - Amazon Cognito Region
,
Storage:
AWSS3:
bucket: Config.S3_BUCKET,
region: Config.S3_REGION,
,
,
);
// In your file
import Storage from 'aws-amplify';
export const S3UploadFile = async (uri, name, type) =>
const file = await fetch(uri);
const blob = await file.blob();
const key = '/' + name;
return Storage.put(key, blob,
contentType: type,
);
;
【讨论】:
我从哪里获得 accessKeyId: AWS_KEY_ID, secretAccessKey: AWS_SECRET, .?? 你可以在编辑后从这里找到这些***.com/questions/44481490/…以上是关于React-native 上传图片到 amazon s3的主要内容,如果未能解决你的问题,请参考以下文章
将图像上传到 Amazon S3 时出现 NotAuthorizedException