以下是我的代码,我试图捕获图像并填充其他输入字段。单击创建按钮后,我将调用一个api将其上传到后端服务器。但是,如何将文件详细信息发送到后端?我有邮递员的工作API。在某些字段中,由于此处代码很大,因此我在此处未包含一些输入字段代码。
API在邮递员中接受以下字段
import React, {Component} from 'react';
import {
StyleSheet,
Button,
TextInput,
Text,
TouchableOpacity,
View,
Picker,
Image,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class CreateStudent extends React.Component {
constructor(props){
super(props);
this.state = {
studentName: '',
email: '',
newPassword: '',
fileShow: '',
faceDetails: '',
school: 1,
}
}
handleEmail = (text) => {
this.setState({ email: text })
}
handlePassword = (text) => {
this.setState({ newPassword: text })
}
handleName = (text) => {
this.setState({ studentName: text })
}
selectImage = () => {
const options = {
quality: 1.0,
maxWidth: 75,
maxHeight: 75
}
ImagePicker.launchCamera(options,(responce)=>{
const fileDetails ={
uri : responce.uri,
name :responce.fileName,
method: 'POST',
width : 50,
height : 50,
path : responce.path,
type : responce.type,
}
this.setState({
fileShow: responce.uri,
faceDetails: fileDetails
})
console.log(this.state.fileShow);
console.log(fileDetails);
})
}
async onCreateStudentPressed() {
try {
let response = await fetch('http://10.0.2.2:5000/api/students/create', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
file: this.state.fileDetails,
email: this.state.email,
password: this.state.newPassword,
phone_number: this.state.phoneNumber,
class: this.state.class,
section: this.state.section,
school: this.state.school,
name: this.state.studentName
})
});
let res = await response.text();
if (response.status >= 200 && response.status < 300) {
//Handle success
let accessToken = res;
console.log(accessToken);
//On success we will store the access_token in the AsyncStorage
//this.storeToken(accessToken);
} else {
//Handle error
let error = res;
throw error;
}
} catch(error) {
this.setState({error: error});
console.log("error " + error);
this.setState({
passwordUpdated: false
})
}
}
render() {
return (
<View>
<View style={styles.formContainer}>
<Text style ={styles.pageTitle} >Create Student</Text>
<View style={styles.Camera}>
<TouchableOpacity onPress={this.selectImage}>
<Text>Take Picture</Text>
</TouchableOpacity>
</View>
{
this.state.fileShow !== '' ?
<View style={styles.showBlack}>
<View style={styles.placeholder}>
<Image key={1} source={{uri: this.state.fileShow}} style={styles.previewImage} />
</View>
</View>
:
null
}
<TextInput
placeholder='Enter Student Name'
placeholderTextColor='#808080'
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handleName}
/>
<TextInput
placeholder='Enter Student Email'
placeholderTextColor='#808080'
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handleEmail}
/>
<TextInput
placeholder='Enter Password'
placeholderTextColor='#808080'
secureTextEntry={true}
style ={styles.textInput}
underlineColorAndroid={'transparent'}
onChangeText = {this.handlePassword}
/>
<Button
onPress={this.onCreateStudentPressed.bind(this)}
style ={styles.loginBtn}
title="Create"
/>
</View>
</View>
);
}
}
答案 0 :(得分:0)
有多种方法可以实现此目的。我将重点介绍最简单的方法。我假设您有一个存储服务,例如Amazon S3,用于存储照片。最简单的方法是您首先将图像上传到S3,响应正文中将包含上传照片的URL。然后,您可以将该URL与表单值一起使用,并将它们传递给后端。
//Example.js
import React, { Component } from 'react';
import {
//Whatever RN Components you need
StyleSheet,
Text,
View,
Alert,
TouchableHighlight,
TextInput,
ActivityIndicator,
ScrollView,
Picker,
Linking,
Image,
} from 'react-native';
import axios from 'axios';
import { RNS3 } from 'react-native-aws3';
import ImagePicker from 'react-native-image-picker';
export default class RegisterScreen extends Component {
state = {
email: '',
password: '',
confirmedPassword: '',
firstName: '',
lastName: '',
avatar: '',
avatarUri: '',
avatarName: '',
avatarType: '',
loading: false,
errorMessage: '',
uploadMessage: ''
}
onRegisterPress = () => {
this.setState({
errorMessage: '',
registerLoading: true,
uploadMessage: 'This may take a while: Uploading your Profile Pic...'
});
const avatarFile = {
uri: this.state.avatarUri,
name: this.state.avatarName,
type: this.state.avatarType
};
const avatarOptions = {
keyPrefix: 'uploads/path/avatar/' + this.state.email + '/' + new Date().getTime(),
bucket: 'your-bucket-s3',
region: 'us-west-2',
accessKey: 'ACCESSKEY',
secretKey: 'SECRETKEY',
successActionStatus: 201
};
RNS3.put(avatarFile, avatarOptions)
.then((response) => {
if (response.status === 201) {
this.setState({ avatar: response.body.postResponse.location });
} else {//handle error}
})
.then(() => {
this.setState({
uploadMessage: 'Creating your profile'
});
const url = 'someremoteurl.com';
const payload = {
email: this.state.email,
password: this.state.password,
password_confirmation: this.state.confirmedPassword,
first_name: this.state.firstName,
last_name: this.state.lastName,
avatar: this.state.avatar,
};
axios.post(url, payload)
.then((r) => {
this.setState({
uploadMessage: '',
loading: false
});
if (r.status === 200) {
//handle success
}
})
.catch(() => {
// handle form submission error
this.setState({
uploadMessage: '',
loading: false,
error: true
});
});
});
}
openMediaLibrary() {
const options = {
title: 'Select Photo',
storageOptions: {
skipBackup: true,
path: 'images'
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('Cancelled selection of image');
} else if (response.error) {
console.log('Image Picker error', response.error)
} else {
this.setState({
avatarUri: response.uri,
avatarName: response.fileName,
avatarType: response.type
});
}
});
}
render() {
return (
<ScrollView style={{ margin: 15 }}>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Email</Text>
<TextInput
placeholder='john@yahoo.com'
underlineColorAndroid='transparent'
onChangeText={(email) => this.setState({ email })}
value={this.state.email}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Password (minimum of 8 letters)</Text>
<TextInput
placeholder='password'
underlineColorAndroid='transparent'
onChangeText={(password) => this.setState({ password })}
value={this.state.password}
secureTextEntry
autoCorrect={false}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> Password Confirmation</Text>
<TextInput
placeholder='retype your password'
underlineColorAndroid='transparent'
onChangeText={(confirmedPassword) => this.setState({ confirmedPassword })}
value={this.state.confirmedPassword}
secureTextEntry
autoCorrect={false}
autoCapitalize='none'
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}> First Name</Text>
<TextInput
placeholder='First Name'
underlineColorAndroid='transparent'
onChangeText={(firstName) => this.setState({ firstName })}
value={this.state.firstName}
/>
</View>
<View style={styles.formField}>
<Text style={styles.formLabelStyle}>Last Name</Text>
<TextInput
placeholder='Last Name'
underlineColorAndroid='transparent'
onChangeText={(lastName) => this.setState({ lastName })}
value={this.state.lastName}
/>
</View>
<View>
<View style={{ padding: 10 }}>
{
this.state.avatarUri.length > 0 ?
<Image
source={{ uri: this.state.avatarUri }}
style={{ width: 140, height: 140 }}
/>
: null
}
</View>
<Button
small
backgroundColor='#13CE66'
title={(this.state.avatarUri.length === 0) ?
'Choose Profile Picture' : 'Change Profile Picture'}
onPress={() => this.openMediaLibrary()}
/>
</View>
<Button
large
backgroundColor='#13CE66'
title='Submit'
onPress={() => this.onRegisterPress() }
/>
</ScrollView>
)
}
}
因此,当您尝试注册该用户时,图像首先被上传,并且所检索的url以状态的形式存储,以用作化身的形式参数的一部分。 这很容易,缺点是必须等待上传响应,然后才能实际发送表单参数
如果您不使用第三方存储服务,或者希望将文件发送到自己的服务器,请使用FormData()
:
//OnRegisterPress function should look like this:
onRegisterPress = () => {
let form = new FormData();
form.append('avatar', {
//from openMedia Function, image selected with image-picker
uri: this.state.avatarUri,
name: this.state.avatarName,
type: this.state.avatarType
});
// append your other params such as email, password, name
form.append('email', this.state.email)
form.append('password', this.state.password)
// when you are done appending, use fetch to send the form data as axios seems to be having a bit of issues doing this.
fetch('http://yourapiendpoint', {
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
method: 'POST',
body: form
});
}