我正在尝试创建一个应用程序,提示用户使用Expo Image Picker从设备库中选择图像,然后将该图像上载到服务器。图片未通过,我认为问题可能与状态变量的值有关,该值应该是图片数据。
这里是我遵循的教程的链接,尽管出现了一些问题,所以我不得不对其进行一些修改: https://heartbeat.fritz.ai/how-to-upload-images-in-a-react-native-app-4cca03ded855
应用代码:
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createAppContainer, createStackNavigator } from 'react-navigation';
import HomeScreen from './components/HomeScreen';
import DetailsScreen from './components/DetailsScreen';
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
navigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
},
);
const AppContainer = createAppContainer(RootStack);
export default AppContainer;
HomeScreen.js
import * as React from 'react';
import { Button, View, Text, Image, Platform } from 'react-native';
import {ImagePicker, Permissions } from 'expo';
import Constants from 'expo-constants';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
state = {
image: null,
};
render() {
const { image } = this.state;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Pick an image from camera roll"
onPress={this._pickImage}
/>
{image &&
<Image source={{ uri: image.uri }} style={{ width: 200, height: 200 }} />}
<Button title="Upload" onPress={this.handleUploadPhoto} />
</View>
);
}
componentDidMount() {
this.getPermissionAsync();
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
});
console.log(result);
if (!result.cancelled) {
this.setState({ image: result });
}
};
handleUploadPhoto = () => {
const data = new FormData();
data.append("photo", {
name: this.state.image.fileName,
type: this.state.image.type,
uri:
Platform.OS === "android" ? this.state.image.uri : this.state.image.uri.replace("file://", "")
});
Object.keys({ userId: "123" }).forEach(key => {
data.append(key, { userId: "123" }[key]);
});
fetch("http://localhost:8888/api/upload", {
method: "POST",
body: data
})
.then(response => response.json())
.then(response => {
console.log("upload succes", response);
alert("Upload success!");
this.setState({ photo: null });
})
.catch(error => {
console.log("upload error", error);
alert("Upload failed!");
});
};
getPermissionAsync = async () => {
if (Constants.platform.ios) {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
}
}
export default HomeScreen;
服务器
index.js
const Express = require('express')
const multer = require('multer')
const bodyParser = require('body-parser')
const app = Express()
app.use(bodyParser.json())
const Storage = multer.diskStorage({
destination(req, file, callback) {
callback(null, './images')
},
filename(req, file, callback) {
callback(null, `${file.fieldname}_${Date.now()}_${file.originalname}`)
},
})
const upload = multer({ storage: Storage })
app.get('/', (req, res) => {
res.status(200).send('You can post to /api/upload.')
})
app.post('/api/upload', upload.array('photo', 3), (req, res) => {
console.log('file', req.files)
console.log('body', req.body)
res.status(200).json({
message: 'success!',
})
})
app.listen(8888, () => {
console.log('App running on http://localhost:8888')
})