我没有在服务器端接收数据。有时我将数据作为对象获取。我尝试了不同的方法,但图像上传失败。下面是我的代码。我尝试了不同的方法,但结果是相同的图像文件夹保持为空,就像使用 multer 中间件
使用此片段显示图像
<TouchableHighlight
style={[
styles.profileImgContainer,
{ borderColor: "#4632a1", borderWidth: 1 },
]}
onPress={openImagePickerAsync}
>
<Image source={{ uri: selectedImage.localUri }} style={styles.thumbnail} />
</TouchableHighlight>
这是图像选择器部分
function PickImage() {
let [selectedImage, setSelectedImage] = useState("");
let openImagePickerAsync = async () => {
let permissionResult =
await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
alert("Permission to access camera roll is required!");
return;
}
let pickerResult = await ImagePicker.launchImageLibraryAsync();
if (pickerResult.cancelled === true) {
return;
}
setSelectedImage({ localUri: pickerResult.uri });
};
}
获取 API 调用
async function upload() {
const data = new FormData();
data.append("image", {
uri: selectedImage.uri,
name: selectedImage.title,
type: selectedImage.type,
});
const setting = {
method: "POST",
headers: {
"Content-Type": "multipart/form-data;",
},
body: data,
};
try {
const fetchResponse = await fetch(url, setting);
const data = await fetchResponse.json();
alert(data);
} catch (e) {
alert(e);
}
}
服务器端代码
app.post("/users", upload.single("image"), async (req, res) => {
console.log(req.body.file);
console.log(req.body);
const img = req.body.image;
if (!img) {
console.log("no image");
}
res.send({ congrats: "data recieved" });
});
首先,
ImagePicker
不返回标题和mimeType。将状态更新逻辑改成这样
setSelectedImage({
uri: result.uri,
name: 'SomeImageName.jpg',
type: 'image/jpg',
});
还将你的上传功能更改为此,(我最喜欢的编写 POST 请求的方式)
async function upload() {
try {
const data = new FormData();
data.append("image", selectedImage);
await fetch(URL_Endpoint, {
method: "POST",
body: data,
});
} catch (error) {
console.log(error);
}
}
其次,在服务器端,这样使用
您可以通过两种方式管理文件
像这样定义 multer 配置
const express = require("express");
const app = express();
const multer = require("multer");
const storage = multer.diskStorage({
destination: "./uploads/",
filename: function (req, file, cb) {
cb(null, "SomeImage" + "." + file.originalname.split(".").pop());
},
});
const diskStorage = multer({ storage: storage });
然后,
app.post("/users", diskStorage.single("image"), async (req, res) => {
try {
console.log(req.file); // File which is uploaded in /uploads folder.
console.log(req.body); // Body
res.send({ congrats: "data recieved" });
} catch (error) {
res.status(500).send("Error");
}
});
像这样定义 multer 配置
const express = require("express");
const app = express();
const fs = require("fs");
const multer = require("multer");
const memoryStorage = multer({
storage: multer.memoryStorage(),
});
然后,
app.post("/users", memoryStorage.single("image"), async (req, res) => {
try {
console.log(req.file);
console.log(req.body);
// Here you will have to save it manually
const DirName = `./uploads`;
let URL = `./uploads/SomeImage.` + req.file.originalname.split(".").pop();
fs.mkdir(DirName, { recursive: true }, async (err) => {
if (err) {
return res.status(500).send("Some Error");
} else {
fs.writeFile(URL, req.file.buffer, "ascii", function (err) {
if (err) {
return res.status(500).send("Some Error");
} else {
res.send({ congrats: "data recieved" });
}
});
}
});
} catch (error) {
res.status(500).send("Error");
}
});
我尝试了不同的方法通过 fetch 和 axios API 发送我的文件,但是 multer 无法找到我的图像 uri,因为它接受文件,因此您可以简单地 stringfy 图像的 uri 并将其发送到您的 Nodejs 服务器,而不是进入这些内容
axios API
const formData=new FormData()
var imageJSON = {
imageName:new Date().getTime()+"_profile",
avatar:selectedImage,
name:name,
email:email,
SocietyCode:sCOde,
password:Password
}
formData.append('image', JSON.stringify(imageJSON))
axios.post('http://localhost:3000/users',formData,{
headers:{
Accept: 'application/json',
'Content-Type':'multipart/form-data'
}
}).then((responseData) => {
console.log("before",responseData.data)
})
.catch((error) => {
alert(error)
console.log("ERROR " + error.message)
});
节点服务器端代码
router.post('/users', upload.single('avatar'), async (req,res)=>{
formData =await req.body;
var userJSON =await JSON.parse(formData.image);
const avatar =await Buffer.from(userJSON.avatar, "utf-8");
delete userJSON.avatar
userJSON.avatar=avatar
console.log(userJSON)
const user= new Users(userJSON)
try{
await user.save()
res.send({'message':'Registeration Successfull'})
}
catch(e){
res.send({'response':'registeration failed'})
console.log(e)
}
})
从这个答案复制粘贴我的代码,以防有人需要它以供将来参考:
App.js
import { useState } from "react";
import { Button, Image, ScrollView, View } from "react-native";
import { launchImageLibrary } from 'react-native-image-picker';
import RNFetchBlob from "rn-fetch-blob";
async function add_images(setImages) {
const images = await launchImageLibrary({ mediaType: 'photo', selectionLimit: 0 });
if (images.didCancel)
return
setImages(val => {
let copy_val = [...val]
images.assets.forEach((item) => {
copy_val.push({ uri: item.uri, filename: item.fileName })
})
return copy_val
});
}
async function upload_images(images) {
let data = []
images.forEach((item, index) => {
data.push({ name: 'images_data', filename: item.filename, data: RNFetchBlob.wrap(item.uri) })
})
// you may have to use another route instead of localhost
RNFetchBlob.fetch('POST', 'localhost:3000/upload_images', { 'Content-Type': 'multipart/form-data' }, data);
}
export default function App() {
const [images, setImages] = useState([]) // array of URIs
return (<>
<View style={{ flexDirection: 'row', justifyContent: 'space-evenly', marginVertical: 50 }}>
<Button title="Add Images" onPress={() => { add_images(setImages) }} />
<Button title="Clear Images" onPress={() => { setImages([]) }} />
<Button title="Upload Images" onPress={() => { upload_images(images) }} />
</View>
<ScrollView horizontal={true}>
{
images.map((item, index) => {
return (<Image key={index} style={{ height: 400, width: 400 }} source={{ uri: item.uri }} />)
})
}
</ScrollView>
</>)
}
node.js
// import fs from 'fs';
import multer from "multer";
import express from 'express';
const server = express();
var upload = multer({ dest: 'uploads/' });
server.post('/upload_images', upload.array('images_data'), (req, res) => {
console.log(req.files);
// req.files.forEach(item => {
// fs.renameSync(item.path, item.destination + item.originalname)
// })
});
const PORT = 3000
server.listen(PORT, () => {
console.log(`listening at ${PORT} ...`);
});