我编写了下面的代码,通过发布请求将图像从 React Native Expo 发送到我的后端。我已经用邮递员测试了后端并确认它可以正常工作。但是,当我发出发送图像的 post 请求时,后端会收到大小为 0 的图像。 在发出发布请求之前,我记录了文件大小并确认它不为零。
export const uploadVerificationPhoto = async (photoUri: string) => {
try {
const blob = await fetch(photoUri).then((r) => r.blob());
const file = new File([blob], `photo.jpeg`, { type: blob.type });
console.log("file:", file.size); //result > 0
const formData = new FormData();
formData.append("driverID", "63cf8420cd6d7a41da6dad91");
formData.append("driverImage", file, "photo.jpeg");
const response = await axios.post(
"http://localhost:10001/api/image/profile-photo",
formData,
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
return response.data;
} catch (error) {
console.error("Error sending photos:", error);
throw error;
}
};
我尝试将文件作为 base64 发送,但 expo 文件系统抛出
uri cannot be read
错误。
我认为问题出在我的后端,所以我使用了 formidable,但仍然遇到同样的问题。
无论我选择图像还是使用展会相机拍照都会出现此问题。
我在 React Native Profile Images 上也遇到了类似的问题,这是我项目中的解决方案:
// Your backend route:
userProfileImages: async (req, res) => {
const file = req.file;
try {
if (!file) {
return res
.status(400)
.json({ success: false, message: "No file provided." });
}
const filePath = file.path;
// console.log(req.file);
const userId = req.user.id;
const fileStats = fs.statSync(filePath);
console.log("File Path: " + filePath);
console.log("File stats:", fileStats);
console.log("Form Data: ", JSON.stringify(req.body));
if (fileStats.size > 0) {
const image = new Image({
userId: userId,
name: file.originalname,
imageUrl: file.path,
contentType: file.mimetype,
size: fileStats.size,
});
// console.log("File stats size: " + fileStats.size);
// console.log("Req file size: " + req.file.size);
await image.save();
return res.status(201).json({
success: true,
message: "Image created successfully.",
imageName: file.originalname,
size: fileStats.size,
});
} else {
return res
.status(500)
.json({ success: false, message: "File is empty." });
}
} catch (error) {
console.error("Error handling image:", error);
return res
.status(500)
.json({ success: false, message: "Internal server error." });
}
},
// You React component
const pickImageAsync = async () => {
try {
const { status } =
await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== "granted") {
return Alert.alert("Sorry, we need your permissions");
}
const result: any = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (result.cancelled) {
return;
}
const selectedAsset = result.assets[0];
setSelectedImage({
uri: selectedAsset.uri,
width: selectedAsset.width || null,
height: selectedAsset.height || null,
type: selectedAsset.type || null,
fileSize: selectedAsset.fileSize || null,
fileName: selectedAsset.filename || null,
});
const localUri = selectedAsset.uri;
const fileName = localUri.split("/").pop();
const formData = new FormData();
formData.append("file", {
uri: selectedAsset.uri,
type: "image/jpeg",
name: fileName || "image.jpg",
} as any);
await deleteImage();
await postImage(formData);
} catch (error) {
console.error("Error in pickImageAsync:", error);
}
};
const postImage = async (formData: FormData) => {
try {
await axios.post("http://localhost:8000/upload", formData, {
headers: {
Authorization: `Bearer ${storedToken}`,
"Content-Type": "multipart/form-data",
},
});
// console.log("Upload Response:", response.data);
} catch (error) {
console.error("Error in postImage:", error);
}
};