我正在使用以下工具做一个小练习:React、Node.js、Express 和 MongoDB。
我正在尝试将图像上传到数据库,然后使用表单显示它。
后端代码如下:
const multer = require('multer')
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({ storage })
app.post('/upload', upload.single('file'), async (req, res) => {
try {
const newFile = new File({
filename: req.file.originalname,
contentType: req.file.mimetype,
destination: req.file.destination,
fileName: req.file.filename,
path: req.file.path,
buffer: req.file.buffer,
fieldname: req.file.fieldname,
data: req.file.buffer
})
// Guardar el documento en la base de datos
const savedImage = await newFile.save()
res.json(savedImage)
} catch (error) {
console.error(error)
res.status(500).send('Error al subir el archivo')
}
})
app.get('/image/:id', async (req, res, next) => {
const { id } = req.params
try {
const file = await File.findById(id)
if (file) {
res.set('Content-Type', file.contentType)
res.send(file.buffer)
} else {
res.status(500).send('Error al buscar la imagen')
}
} catch (error) {
next(error)
}
})
前端代码如下:
function App() {
const { register, handleSubmit } = useForm();
const [imagen , setImagen] = useState(null);
const [loading, setLoading] = useState(false);
const onSubmit = async (data) => {
setLoading(true);
const formData = new FormData();
formData.append("file", data.file[0]);
try {
const response = await axios.post('http://localhost:3001/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
const res = await axios.get(`http://localhost:3001/image/${response.data.id}`);
setImagen(res.data);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<input type="file" {...register("file")} />
<button type="submit" disabled={loading}>{loading ? "Cargando..." : "Enviar"}</button>
</form>
{imagen && (
<div>
<h1>Imagen:</h1>
<img src={`http://localhost:3001/${imagen.path}`} alt={imagen.fileName} width="500" height="600" />
</div>
)
}
</div>
);
}
export default App;
代码本身有效,但我不明白为什么它不显示图像。
有谁知道错误在哪里或为什么它不起作用? 非常感谢。
如果使用
multer
和storage: multer.diskStorage(...)
,文件将被上传到磁盘,req.file.buffer
将not被填充。填充它意味着文件必须保存在内存中,这就是 diskStorage
的目的。
要查看文件内容,您必须再次从磁盘加载文件。这可以做为
fs.readFileSync(req.file.path)
但是,这又一次将整个文件加载到内存中。然而,这可能是你无法避免的事情,除非你可以将文件流式传输到你的 mongodb 中。