英文:
How to fix Multer middleware when it fails to create upload folder and change filename?
问题
我尝试使用Node.js和Multer将PDF文件上传到服务器,但出现了问题。我从ejs模板发送文件,文件必须保存在名为upload的文件夹中,并更改文件名为特定名称,但Multer中间件似乎不起作用,没有创建文件夹,也没有更改文件名。
以下是代码的部分内容。
ejs文件:
<form enctype="multipart/form-data">
<input type="text" placeholder="Book Name" id="name" />
<input type="text" placeholder="Author" id="author" />
<input type="text" placeholder="Buy link" id="link" />
<input type="text" placeholder="Book description" id="desc" />
<input type="file" name="pdf" id="pdf" placeholder="upload file" />
<button type="submit">Add</button>
</form>
<script>
let form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
let bookName = document.getElementById("name").value;
let bookAuthor = document.getElementById("author").value;
let bookLink = document.getElementById("link").value;
let bookDesc = document.getElementById("desc").value;
let pdf = document.getElementById("pdf").files[0].name;
e.preventDefault();
try {
const res = await fetch("/addBooks", {
method: "POST",
body: JSON.stringify({
bookName,
bookAuthor,
bookDesc,
bookLink,
pdf,
}),
headers: { "Content-Type": "application/json" },
});
}
</script>
中间件:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "upload");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
console.log(destination, filename);
},
});
const upload = multer({ storage });
route.post("/addBooks", upload.single("pdf"), addBook);
POST函数:
let addBook = async (req, res) => {
console.log("reqbody >> ", req.body);
let { bookName, bookAuthor, bookDesc, bookLink, pdf } = req.body;
try {
let _book = await books.create({
name: bookName,
author: bookAuthor,
description: bookDesc,
buyLink: bookLink,
pdf: pdf,
});
if (_book) {
res.status(200).send({ msg: "success" });
}
} catch (error) {
logger.error("系统崩溃,请再试一次");
res.status(400).send({ msg: "错误" });
}
};
注意:你的ejs文件中有一处错误,应该使用document.getElementById("pdf")
而不是 document.getElementById("myfile")
来获取文件输入元素。
英文:
i am trying to upload pdf to server using nodejs and multer but there is a problem.
a send a file from ejs templet and it must be saved at disk on folder named upload and file name changed to specific name .
but what happen that Multer middleware does not work no folder created no filename changed
There are parts of code .
ejs file
<form enctype="multipart/form-data">
<input type="text" placeholder="Book Name" id="name" />
<input type="text" placeholder="Author " id="author" />
<input type="text" placeholder="Buy link" id="link" />
<input type="text" placeholder="Book description" id="desc" />
<input type="file" name="pdf" id="pdf" placeholder="upload file" />
<button type="submit">Add</button>
</form>
<script>
// const multer = import("multer");
// const upload = multer({ dest: "./public/data/uploads/" });
let form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
let bookName = document.getElementById("name").value;
let bookAuthor = document.getElementById("author").value;
let bookLink = document.getElementById("link").value;
let bookDesc = document.getElementById("desc").value;
let pdf = document.getElementById("myfile").files[0].name;
e.preventDefault();
try {
const res = await fetch("/addBooks", {
method: "POST",
body: JSON.stringify({
bookName,
bookAuthor,
bookDesc,
bookLink,
pdf,
}),
headers: { "Content-Type": "application/json" },
});
</script>
middleware:
onst storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "upload");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
console.log(destination, filename);
},
});
const upload = multer({ storage });
route.post("/addBooks", upload.single("pdf"), addBook);
post func
let addBook = async (req, res) => {
console.log("reqbody >> ", req.body);
let { bookName, bookAuthor, bookDesc, bookLink, pdf } = req.body;
try {
let _book = await books.create({
name: bookName,
author: bookAuthor,
description: bookDesc,
buyLink: bookLink,
pdf:pdf,
});
if (_book) {
res.status(200).send({ msg: "success" });
}
} catch (error) {
logger.error("system crashed try again ");
res.status(400).send({ msg: "Wrong" });
}
};
答案1
得分: 2
当发送文件时,您必须以表单形式发送它,信息会包含在 req.file 中,而不是 req.body 中。
英文:
When sending a file, you must send it in the form, and the information comes in req.file, not in req.body
答案2
得分: 1
为了上传文件,您需要发送multipart/form-data
请求,而不是JSON请求,您可以使用FormData来实现这一点。
您可以轻松地从HTML表单构建FormData负载,然后在服务器上从req.file
中读取pdf
,而不是从请求体中读取(您可以使用req.file.filename
添加文件名)。
尝试以下方法(您需要添加name
属性,这些属性将与服务器上的req.body
对应):
HTML:
<form enctype="multipart/form-data">
<input type="text" placeholder="Book Name" id="name" name="name" />
<input type="text" placeholder="Author " id="author" name="author" />
<input type="text" placeholder="Buy link" id="link" name="link" />
<input type="text" placeholder="Book description" id="desc" name="desc" />
<input type="file" name="pdf" id="pdf" placeholder="upload file" />
<button type="submit">Add</button>
</form>
<script>
let form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const formData = new FormData(form);
console.log('form fields: ', Object.fromEntries(formData.entries()));
try {
const res = await fetch("/addBooks", {
method: "POST",
body: formData
});
console.log('ok', res);
} catch(err) {
console.log(err);
}
});
</script>
服务器:
let addBook = async (req, res) => {
console.log("reqbody >> ", req.body);
let { name, author, desc, link} = req.body;
let pdf = req.file.filename;
console.log( name, author, desc, link, pdf);
try {
let _book = await books.create({
name,
author,
description: desc,
buyLink: link,
pdf
});
if (_book) {
res.status(200).send({ msg: "success" });
}
} catch (error) {
logger.error("system crashed try again ");
res.status(400).send({ msg: "Wrong" });
}
};
英文:
To upload a file, you need to post multipart/form-data
request, not JSON, for which you can use FormData.
You could easily construct FormData payload from HTML form, and then on the server, read pdf
from req.file
, not body. (you can add file name with req.file.filename
).
Try this (you need to add name
attributes, which will correspond to those from req.body
on the server):
HTML:
<form enctype="multipart/form-data">
<input type="text" placeholder="Book Name" id="name" name="name" />
<input type="text" placeholder="Author " id="author" name="author" />
<input type="text" placeholder="Buy link" id="link" name="link" />
<input type="text" placeholder="Book description" id="desc" name="desc" />
<input type="file" name="pdf" id="pdf" placeholder="upload file" />
<button type="submit">Add</button>
</form>
<script>
let form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const formData = new FormData(form);
console.log('form fields: ', Object.fromEntries(formData.entries()));
try {
const res = await fetch("/addBooks", {
method: "POST",
body: formData
});
console.log('ok', res);
} catch(err) {
console.log(err);
}
});
</script>
server:
let addBook = async (req, res) => {
console.log("reqbody >> ", req.body);
let { name, author, desc, link} = req.body;
let pdf = req.file.filename;
console.log( name, author, desc, link, pdf);
try {
let _book = await books.create({
name,
author,
description: desc,
buyLink: link,
pdf
});
if (_book) {
res.status(200).send({ msg: "success" });
}
} catch (error) {
logger.error("system crashed try again ");
res.status(400).send({ msg: "Wrong" });
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论