我无法将文件上传到我使用 node js multer 指定的目录
Posted
技术标签:
【中文标题】我无法将文件上传到我使用 node js multer 指定的目录【英文标题】:I cannot upload files to the directory I specified using node js multer 【发布时间】:2020-07-17 08:19:27 【问题描述】:我使用节点 js 创建了一个 Web 服务。我创建了一个带有 React 界面的表单,并添加了用户信息和文件上传。我将此信息保存到 mongodb。我想使用 multer 将文件保存到节点 js 服务器,但没有将文件添加到我指定的目录中。我需要解决什么问题?
路线
const express = require('express')
const User = require('../models/index')
const router = express.Router()
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: storage )
/* create new*/
router.post('/', upload.single('image'), (req,res)=>
user = new User(
name:req.body.name,
email:req.body.email,
password:req.body.password,
img: req.file
);
user.save(()=>
res.json(user)
)
);
/* find all users */
router.get('/', (req, res) =>
User.find(,(err,data) =>
res.json(data)
)
);
/* find user by id */
router.get('/:id',(req, res) =>
User.findById(req.params.id, (err, data) =>
res.json(data)
)
);
/* delete user by id */
router.delete('/:id',async (req, res) =>
await User.findByIdAndDelete(req.params.id)
res.json('message':'deleted')
);
/* update */
router.put('/:id', async (req, res)=>
await User.findByIdAndUpdate(req.params.is, req.body)
res.json('message':'updated')
);
module.exports = router;
服务器/index.js
const express = require('express');
const mongoose = require('mongoose');
const mongodb = require('mongodb');
const cors = require('cors');
mongoose.connect('mongodb://localhost:27017/admin?authSource=$[authSource] --username $[username]', useNewUrlParser : true);
const app = express();
app.use(express.json());
app.use(cors());
app.use(express.urlencoded(extended:true));
app.use('/api',require('./routes/index'));
const port = process.env.PORT || 8080;
app.listen(port);
module.exports = new mongoose.model('User', newSchema);
反应方面
import React, Component from 'react';
import axios from 'axios';
class App extends React.Component
constructor(props)
super(props);
this.state =
users: [],
id: 0,
name: '',
email: '',
password: '',
img: ''
componentDidMount()
try
axios.get('http://localhost:8080/api')
.then((res) =>
this.setState(
users: res.data,
id: 0,
name: '',
email: '',
password: '',
img: ''
)
)
catch (e)
console.log(e)
nameChange = event =>
this.setState(
name: event.target.value
)
emailChange = event =>
this.setState(
email: event.target.value
)
passwordChange = event =>
this.setState(
password: event.target.value
)
fileSelectedHandler = event =>
this.setState(
img : event.target.files[0]
)
submit(event, id)
event.preventDefault();
const data = new FormData();
data.append('name', this.state.name);
data.append('password', this.state.password);
data.append('email', this.state.email);
data.append('image', this.state.img);
if (id === 0)
axios.post('http://localhost:8080/api', data).then(()=>
this.componentDidMount()
)
else
axios.put('http://localhost:8080/api/'+id, data).then(()=>
this.componentDidMount()
)
deleteUser(id)
try
axios.delete('http://localhost:8080/api/' + id)
.then((res) =>
this.componentDidMount()
)
console.log('Deleted successfully.')
catch (e)
console.log(e)
editUser(id)
try
axios.get('http://localhost:8080/api/' + id)
.then((res) =>
console.log(res.data)
this.setState(
id:res.data._id,
name: res.data.name,
email: res.data.email,
password: res.data.password,
img : res.data.img.name
)
)
catch (e)
console.log(e)
render()
return (
<div className="row">
<div className="col s6">
<form onSubmit=(e) => this.submit(e, this.state.id)>
<div className="input-field col s12">
<i className="material-icons prefix">person</i>
<input value=this.state.name onChange=(e) => this.nameChange(e) type="text" id="autocomplete-input"
className="autocomplete" required/>
<label htmlFor="autocomplete-input">Name</label>
</div>
<div className="input-field col s12">
<i className="material-icons prefix">mail</i>
<input value=this.state.email onChange=(e) => this.emailChange(e) type="email" id="autocomplete-input"
className="autocomplete" required/>
<label htmlFor="autocomplete-input">Email</label>
</div>
<div className="input-field col s12">
<i className="material-icons prefix">***_key</i>
<input value=this.state.password onChange=(e) => this.passwordChange(e) type="password" id="autocomplete-input"
className="autocomplete" required/>
<label htmlFor="autocomplete-input">Password</label>
</div>
<div className="input-field col s12">
<input type="file" name="file" onChange=(e) => this.fileSelectedHandler(e)/>
</div>
<br/>
<button className="btn waves-effect waves-light right blue" type="submit" name="action">Submit
<i className="material-icons right">send</i>
</button>
</form>
</div>
<div className="col s6">
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Password</th>
<th>IMG</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
this.state.users.map(user =>
<tr key=user._id>
<td>user.name</td>
<td>user.email</td>
<td>user.password</td>
<td>
<img src="./public/uploads/user.img.name" />
</td>
<td>
<button onClick=(e) => this.editUser(user._id)
className="btn waves-effect waves-light green" type="submit" name="action">
<i className="material-icons right">edit</i>
</button>
</td>
<td>
<button onClick=(e) => this.deleteUser(user._id)
className="btn waves-effect waves-light red" type="submit" name="action">
<i className="material-icons right">delete</i>
</button>
</td>
</tr>
)
</tbody>
</table>
</div>
</div>
);
export default App;
【问题讨论】:
【参考方案1】:我可以在您的代码中看到两个问题。
在服务器端,上传的文件位于请求对象的file
-property 下,而不是body
-property。您还需要将名称设置为multer single
-call 上上传的文件,即image
:
router.post('/', upload.single('image'), (req,res)=>
...
const image = req.file; // req.file contains the image
// req.body holds the other fields like name, email, ...
...
);
在反应方面,您应该发送 formData 而不是 json(json 是默认值):
const data = new FormData();
data.append('image', this.state.img);
data.append('email', this.state.name);
// ... append the remaining fields
axios.post('http://localhost:8080/api', data)
.then(() =>
this.componentDidMount()
);
// in the view also use the correct name
...
<input type="file" name="image" onChange=(e) => this.fileSelectedHandler(e)/>
...
【讨论】:
我试图实现你所说的,我编辑了我在问题中分享的代码块。如果我问,你能检查一下吗?这次没有post请求,以前可以在mongodb上注册name、password、email等字段,但现在不行。表单数据不正确吗? 不幸的是我现在不能自己测试它,但我认为你需要添加一个body-parser而不是express.json()
。请检查这些答案-> ***.com/a/43197040/3761628 ***.com/a/61025053/3761628以上是关于我无法将文件上传到我使用 node js multer 指定的目录的主要内容,如果未能解决你的问题,请参考以下文章
我无法使用 node js 将来自 Json 的数据注入带有 angularjs 的 html
如何使用 node.js 获取图像上传进度并在我的 iphone 应用程序中使用它