我使用MaterialUI中的上传组件创建了一个图像上传组件。我过去只使用html文件输入就可以做到这一点,所以我很困惑。这些文件被选择得很好,并将它们置于组件状态。当我将它们附加到表单数据并发送到服务器(node&expressjs)时,我一直从req.files中获得一个空数组。我在服务器端使用multer来解析文件。
以下是UI组件:
const StepFive = ({
handlePrevStep,
setListingImages,
listingImages,
createdListing,
}) => {
const created = useSelector((state) => state.listings.created);
const [fileList, setFileList] = React.useState([]);
const dispatch = useDispatch();
React.useEffect(() => {
setListingImages(fileList);
console.log(fileList);
}, [fileList]);
const onChange = ({ fileList: newFileList }) => {
setFileList(newFileList);
};
const handleLisitingImages = (e) => {
e.preventDefault();
const data = new FormData();
//check if image(s) have been selected yet
//and append the images to form data
if (fileList) {
for (let i = 0; i < fileList.length; i++) {
data.append('listingImage', fileList[i]);
}
}
console.log(data.getAll('listingImage'));
uploadImagesToListing(createdListing._id, data)(dispatch);
};
const onPreview = async (file) => {
let src = file.url;
if (!src) {
src = await new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(file.originFileObj);
reader.onload = () => resolve(reader.result);
});
}
const image = new Image();
image.src = src;
const imgWindow = window.open(src);
imgWindow.document.write(image.outerHTML);
};
// const prevStep = (e) => {
// e.preventDefault();
// handlePrevStep();
// };
// if (!created) return <Spinner />;
return (
<Con>
<Wrap>
<Header>
Step <b>5|5</b>
</Header>
<SubHeader>Pictures</SubHeader>
<SubInfo>
This is the most important part of creating a listing and attratcing
guests. Really spend time on taking some good quality pictures of your
place
</SubInfo>
<UploadForm enctype='multipart/form-data'>
<ImgCrop rotate>
<Upload
listType='picture-card'
fileList={fileList}
onChange={onChange}
onPreview={onPreview}
name='image'
>
{fileList.length < 15 && '+ Upload'}
</Upload>
</ImgCrop>
</UploadForm>
<BtnCon>
<Btn onClick={prevStep}>Prev</Btn>
<Btn onClick={handleLisitingImages}>Finish</Btn>
</BtnCon>
</Wrap>
</Con>
);
};
这里是uploadImagesToListing函数:
export const uploadImagesToListing = (listingId, images) => async (dispatch) => {
await axiosInstance
.post(`/listings/imageupload/${listingId}`, images, {
headers: { 'Content-Type': `multipart/form-data;` },
})
.then((res) => {
dispatch({
type: uploadedImages,
});
})
.catch((err) => {
console.log(err);
});
};
现在服务器上有一条带multer的路线:
const storage = multer.memoryStorage();
//allows routes to get files
const multipleUpload = multer({ storage: storage }).array('listingImage');
router.post(
'/imageupload/:listingId',
verifyToken,
multipleUpload,
listings.imageUpload
);
在路由处理程序中,我所做的只是尝试console.log(req.files)并不断获得一个空数组。
解决了的
当从输入访问每个文件对象时,我需要添加fileList[I].originalfileObject,而不仅仅是fileList[I]