Javascript 将本机上载图像反应到amazons s3
我想将图片从我的应用程序上传到S3服务器。我已经计算了所有数据和代码(在计算机上使用curl进行测试),但我不知道如何正确调用“fetch”。我得到的回应是: '您指定的至少一个先决条件不适用。条件:斗杆必须为外壳型多部件/表格数据' 如何在react natives fetch中重新创建表单数据?并没有FormData可以像fetches示例中那个样附加并发送它 编辑: 感谢@philipp von weitershausen,感谢您添加了此功能。然而,我有一些麻烦叫它。我得到了“不支持的BodyInit类型”。发现这是因为在fetch.js中:“support.formData”返回false。当我打电话给fetch时,我错过了什么 我的代码示例:Javascript 将本机上载图像反应到amazons s3,javascript,file-upload,amazon-s3,fetch,react-native,Javascript,File Upload,Amazon S3,Fetch,React Native,我想将图片从我的应用程序上传到S3服务器。我已经计算了所有数据和代码(在计算机上使用curl进行测试),但我不知道如何正确调用“fetch”。我得到的回应是: '您指定的至少一个先决条件不适用。条件:斗杆必须为外壳型多部件/表格数据' 如何在react natives fetch中重新创建表单数据?并没有FormData可以像fetches示例中那个样附加并发送它 编辑: 感谢@philipp von weitershausen,感谢您添加了此功能。然而,我有一些麻烦叫它。我得到了“不支持的Bo
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();
multipart/form data
支持混合有效载荷(JS字符串+图像有效载荷)的React Native(通过XHRFormData
API)。它很快就会登陆GitHub。有人问,所以我在这里发布我是如何做到的。这是很久以前安静地完成的,所以如果你有任何评论或某些事情做得很糟糕,我愿意接受批评;)
照片从cameraRoll读取并存储在“latestPhoto”中
正在将照片上载到S3服务器:
步骤1:生成数据:
_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 });
},
\u send(){
此参数。_addTextParam()
var xhr=new XMLHttpRequest();
xhr.open('POST',“http://“+this.state.fs_domain+”+this.state.server);
xhr.onload=()=>{
this.setState({isUploading:false});
如果(xhr.status!==201){
警报(
“上载失败”,
'预期HTTP 200正常响应,获得'+xhr.status+“/”+xhr.responseText
);
返回;
}
如果(!xhr.responseText){
警报(
“上载失败”,
“无响应有效负载。”
);
返回;
}
var index=xhr.responseText.indexOf(“http://“+this.state.fs\u domain+”+this.state.server);
如果(索引==-1){
警报(
“上载失败”,
“无效响应负载。”
);
返回;
}
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('@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();
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>
);
}
}
}
class YourComponent扩展组件{
// ...
//文件源看起来像:{uri:content://media/external/images/media/13“,isStatic:true}
异步上传FileToS3(文件源){
试一试{
var formData=new formData();
//通过S3选项准备formData
Object.key(this.state.s3options.fields).forEach((key)=>{
append(key,this.state.s3options.fields[key]);
});
append('文件'{
uri:fileSource.uri,
键入:“图像/jpeg”,
});
formData.append('Content-Type','image/jpeg')
var request=new XMLHttpRequest();
request.onload=函数(e){
如果(e.target.status===204){
//导致e.target.responseHeaders.Location
this.setState({avatarSourceRemote:{uri:e.target.responseHeaders.Location}})
}
}.绑定(此)
request.open('POST',this.state.s3options.url,true);
setRequestHeader('Content-type','multipart/formdata');
请求。发送(formData);
}捕获(错误){
控制台错误(error);
}
}
//示例显示上载的图像
render(){
if(this.state.avatarSourceRemote){
返回(
);
}否则{
返回(
没有图像
);
}
}
}
aa它登陆了:太棒了!!我看到你在调用fetch的方法中也改变了一些东西?它停止工作或显示错误:undefined不是一个函数(评估RCTDataMenager.queryData('http',{methode:method,url:url,data:data,headers:headers}).有没有可能快速提示发生了什么变化?没关系,我有两个版本的react native,但在这个文件夹中彼此都不喜欢…你有没有关于这方面的最终工作代码的示例?我也遇到了问题。事实上,你有没有能够发布表单变量的示例(没有图像-看到下一个RN构建添加了图像支持)。可以为您这样做。您是如何生成签名的?我在网上找到的所有模块都依赖于一些节点功能,如http
和fs
@harrymoro Photo是由:加载的,我从Ruby on Rails编写的主应用程序中获取签名。但我认为您可以基于AWS文档重新创建它umtations.accessKeyId:AWS\u KEY\u ID,secretAccessKey:AWS\u SECRET,我从哪里获取?编辑后,您可以在这里找到这些
//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,
});
};