React,Node,Mongodb:我的图像文件不是从后端提供的,试图在 React 端渲染它会抛出 404 not found
React, Node, Mongodb : My image file is not being served from backend and trying to render it on the React side throws 404 not found
我正在从 React 前端上传图片。
constructor(props) {
super(props);
this.state = {
uploadRecipesFormData: {},
selectedFile: null,
redirect : null,
};
}
uploadRecipe = () => {
const formData = new FormData();
formData.append('file', this.state.selectedFile, this.state.selectedFile.name);
for(const key in this.state.uploadRecipesFormData){
formData.append(key, this.state.uploadRecipesFormData[key]);
}
axios.post(`http://localhost:3000/recipes`, formData, {})
.then(res => {
alert(res.data);
this.setState({
redirect: "/uploaded-recipes"
});
})
.catch(err => console.error(err));
}
onChangeImageHandler = e => {
this.setState({
selectedFile: e.target.files[0]
});
}
handleChange = e => {
e.preventDefault();
this.handleInputChange(e.target.name, e.target.value);
}
handleInputChange = (key, value) => {
this.setState({
uploadRecipesFormData: {
_id: uuidv4(),
...this.state.uploadRecipesFormData,
addedBy: 'guest',
[key]: value
}
});
}
submitRecipe = e => {
e.preventDefault();
this.uploadRecipe();
}
我在后端接收图像和其他表单数据:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images')
},
filename: (req, file, cb) => {
cb(null, `${file.originalname} `)
}
});
const upload = multer({ storage: storage }).single('file');
/*
Endpoint: /recipes
Outcome: Add recipe
*/
router.post('/', (req, res) => {
upload(req,res, err => {
if(err instanceof multer.MulterError) {
return res.status(500).json(err);
}
else if(err) {
return res.status(500).json(err);
}
console.log(req.file.filename);
console.log(req.body);
const newRecipeData = new Recipe({
_id: req.body._id,
name: req.body.name,
ingredients: req.body.ingredients.split(','),
instructions: req.body.instructions,
cuisine: req.body.cuisine || '',
image: `http://localhost:3000/images/${req.file.filename}` || '',
addedBy: req.body.addedBy || ''
});
newRecipeData.save()
.then(result => {
res.status(201).send('Recipe added successfully!');
})
.catch(err => console.log(err));
});
});
数据存储在 MongoDb 中,路径为 public 图像目录。但是,此文件存储为二进制文件而不是图像文件。
我在 app.js:
中启用了 express static
app.use(express.static('public'));
我能够在 public/images 文件夹中看到该文件,但它是一个二进制文件,因此当我尝试从我的 React 前端访问它时,它会抛出 404 错误。然后我手动尝试将实际图像添加到 public/images 文件夹并且它起作用了。如何在从前端接收文件数据时保留文件类型?网上的答案我不清楚我在做什么。
您的代码似乎没问题,但是,我可以在这段代码中发现一个可能导致错误的小错误:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images')
},
filename: (req, file, cb) => {
cb(null, `${file.originalname} `)
}
});
这里${file.originalname}
后面多了一个space
cb(null, `${file.originalname} `)
语句。额外的 space 会更改文件名,因此,它显示为二进制文件,您无法从前端访问它。尝试删除那个 space 看看它是否有效。
我正在从 React 前端上传图片。
constructor(props) {
super(props);
this.state = {
uploadRecipesFormData: {},
selectedFile: null,
redirect : null,
};
}
uploadRecipe = () => {
const formData = new FormData();
formData.append('file', this.state.selectedFile, this.state.selectedFile.name);
for(const key in this.state.uploadRecipesFormData){
formData.append(key, this.state.uploadRecipesFormData[key]);
}
axios.post(`http://localhost:3000/recipes`, formData, {})
.then(res => {
alert(res.data);
this.setState({
redirect: "/uploaded-recipes"
});
})
.catch(err => console.error(err));
}
onChangeImageHandler = e => {
this.setState({
selectedFile: e.target.files[0]
});
}
handleChange = e => {
e.preventDefault();
this.handleInputChange(e.target.name, e.target.value);
}
handleInputChange = (key, value) => {
this.setState({
uploadRecipesFormData: {
_id: uuidv4(),
...this.state.uploadRecipesFormData,
addedBy: 'guest',
[key]: value
}
});
}
submitRecipe = e => {
e.preventDefault();
this.uploadRecipe();
}
我在后端接收图像和其他表单数据:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images')
},
filename: (req, file, cb) => {
cb(null, `${file.originalname} `)
}
});
const upload = multer({ storage: storage }).single('file');
/*
Endpoint: /recipes
Outcome: Add recipe
*/
router.post('/', (req, res) => {
upload(req,res, err => {
if(err instanceof multer.MulterError) {
return res.status(500).json(err);
}
else if(err) {
return res.status(500).json(err);
}
console.log(req.file.filename);
console.log(req.body);
const newRecipeData = new Recipe({
_id: req.body._id,
name: req.body.name,
ingredients: req.body.ingredients.split(','),
instructions: req.body.instructions,
cuisine: req.body.cuisine || '',
image: `http://localhost:3000/images/${req.file.filename}` || '',
addedBy: req.body.addedBy || ''
});
newRecipeData.save()
.then(result => {
res.status(201).send('Recipe added successfully!');
})
.catch(err => console.log(err));
});
});
数据存储在 MongoDb 中,路径为 public 图像目录。但是,此文件存储为二进制文件而不是图像文件。 我在 app.js:
中启用了 express static
app.use(express.static('public'));
我能够在 public/images 文件夹中看到该文件,但它是一个二进制文件,因此当我尝试从我的 React 前端访问它时,它会抛出 404 错误。然后我手动尝试将实际图像添加到 public/images 文件夹并且它起作用了。如何在从前端接收文件数据时保留文件类型?网上的答案我不清楚我在做什么。
您的代码似乎没问题,但是,我可以在这段代码中发现一个可能导致错误的小错误:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images')
},
filename: (req, file, cb) => {
cb(null, `${file.originalname} `)
}
});
这里${file.originalname}
后面多了一个space
cb(null, `${file.originalname} `)
语句。额外的 space 会更改文件名,因此,它显示为二进制文件,您无法从前端访问它。尝试删除那个 space 看看它是否有效。