如何修复Multer中间件在无法创建上传文件夹并更改文件名时的问题?

huangapple go评论82阅读模式
英文:

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

 &lt;form enctype=&quot;multipart/form-data&quot;&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Book Name&quot; id=&quot;name&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Author &quot; id=&quot;author&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Buy link&quot; id=&quot;link&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Book description&quot; id=&quot;desc&quot; /&gt;
        &lt;input type=&quot;file&quot; name=&quot;pdf&quot; id=&quot;pdf&quot; placeholder=&quot;upload file&quot; /&gt;
        &lt;button type=&quot;submit&quot;&gt;Add&lt;/button&gt;
      &lt;/form&gt;
&lt;script&gt;
      // const multer = import(&quot;multer&quot;);
      // const upload = multer({ dest: &quot;./public/data/uploads/&quot; });
      let form = document.querySelector(&quot;form&quot;);
      form.addEventListener(&quot;submit&quot;, async (e) =&gt; {
        let bookName = document.getElementById(&quot;name&quot;).value;
        let bookAuthor = document.getElementById(&quot;author&quot;).value;
        let bookLink = document.getElementById(&quot;link&quot;).value;
        let bookDesc = document.getElementById(&quot;desc&quot;).value;
        let pdf = document.getElementById(&quot;myfile&quot;).files[0].name;
        e.preventDefault();
        try {
          const res = await fetch(&quot;/addBooks&quot;, {
            method: &quot;POST&quot;,
            body: JSON.stringify({
              bookName,
              bookAuthor,
              bookDesc,
              bookLink,
              pdf,
            }),
            headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },
          });
&lt;/script&gt;

middleware:

onst storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, &quot;upload&quot;);
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + &quot;-&quot; + file.originalname);
    console.log(destination, filename);
  },
});
const upload = multer({ storage });

route.post(&quot;/addBooks&quot;, upload.single(&quot;pdf&quot;), addBook);

post func

let addBook = async (req, res) =&gt; {
  console.log(&quot;reqbody &gt;&gt; &quot;, 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: &quot;success&quot; });
    }
  } catch (error) {
    logger.error(&quot;system crashed try again &quot;);
    res.status(400).send({ msg: &quot;Wrong&quot; });
  }
};

答案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:

&lt;form enctype=&quot;multipart/form-data&quot;&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Book Name&quot; id=&quot;name&quot; name=&quot;name&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Author &quot; id=&quot;author&quot; name=&quot;author&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Buy link&quot; id=&quot;link&quot; name=&quot;link&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Book description&quot; id=&quot;desc&quot; name=&quot;desc&quot; /&gt;
        &lt;input type=&quot;file&quot; name=&quot;pdf&quot; id=&quot;pdf&quot; placeholder=&quot;upload file&quot; /&gt;
        &lt;button type=&quot;submit&quot;&gt;Add&lt;/button&gt;
      &lt;/form&gt;
&lt;script&gt;

      let form = document.querySelector(&quot;form&quot;);

      form.addEventListener(&quot;submit&quot;, async (e) =&gt; {

        e.preventDefault();

        const formData = new FormData(form);

        console.log(&#39;form fields: &#39;,  Object.fromEntries(formData.entries()));

        try {
          const res = await fetch(&quot;/addBooks&quot;, {
            method: &quot;POST&quot;,
            body: formData
          });
          console.log(&#39;ok&#39;, res);
         } catch(err) {
         	console.log(err);
         }
        });

&lt;/script&gt;

server:

let addBook = async (req, res) =&gt; {
  
  console.log(&quot;reqbody &gt;&gt; &quot;, 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: &quot;success&quot; });
    }
  } catch (error) {
    logger.error(&quot;system crashed try again &quot;);
    res.status(400).send({ msg: &quot;Wrong&quot; });
  }
};

huangapple
  • 本文由 发表于 2023年6月1日 21:32:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76382439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定