Multer自定义文件名:将req.body.inputTextField作为文件名。

3

我无法弄清如何将req.body.fname用作文件名,甚至尝试使用中间件,但req.body为空。

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path);
  },
  filename: function (req, file, cb) {
    cb(null, req.body.fname)  // undefined 
  }
})
var upload = multer({ storage: storage })

app.get('/upload', upload.single('fname'), (req,res)=>{
  .......
})

i m unable to figure out how to fetch fname in fileName
index.html

<form action="/upload" method="POST" enctype= "multipart/form-data">
  <input type="text" name="fname">
  <input type="file" name="pic">
  <input type = "submit">
</form>

3个回答

5
这并不是一种优雅的方式,但胜过什么都没有。


multer无法做到的事情


据我所知,Multer仅在实际文件发送后才发送req.body字段。因此,在为文件命名时,您将无法访问字段。由于enctype设置为multipart,Body Parser也将停止工作。

您可以在哪里获取req.body


虽然较晚,但Multer实际上在上传文件后发送req.body字段。这些字段将在上传文件后可用:

app.post('/upload', (req, res) => {
  upload(req, res, function (err) {
    console.log(req.body.fname) // Here it works
  });
});

一个简单的解决方案


现在我们上传图片后,会得到一个名为“undefined”的文件(顺便提一下,您可能需要添加扩展名,我等一下会讲到)。我们可以通过req.file.path访问它的路径。现在我们调用fs来重命名它,它是Node.js本地支持的,因此无需安装。在使用之前,只需简单地require它:

const fs = require('fs');

然后我们回到上传的过程中。
app.post('/upload', (req, res) => {
  upload(req, res, function (err) {
    fs.renameSync(req.files.path, req.files.path.replace('undefined', req.body.fname));
    // This get the file and replace "undefined" with the req.body field.
  });
});

我假设你的文件路径中没有一个名为“undefined”的文件夹。如果不幸出现这种情况,只需使用Multer命名文件并稍后使用fs.renameSync进行替换。
最后一步:添加扩展名
如果您不打算在HTML输入字段中输入扩展名,则可以在命名过程中附加扩展名。要获取扩展名,我们可以使用path,它也是Node.js的本机模块,只需要被引用即可。
const path = require('path');

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path);
  },
  filename: function (req, file, cb) {
    cb(null, req.body.fname + path.extname(file.originalname))
  }
})

如果你真的想要一个".undefined"的扩展名,只需在文件系统重命名过程中稍后附加扩展名即可。

希望这可以解决你的问题。祝编码愉快!


0

我也遇到了文件名的问题。我通过将其传递给查询来解决它。

  const storage = multer.diskStorage({
  destination: "uploads/",
  filename: (req, file, cb) => {
    cb(null, req.query.filename + path.extname(file.originalname));
  },
});

根据RESTful API的规范,最好将其放在参数中,但我发现使用查询更加方便,而且如果有多个文件也可以接受多个查询。

0

multer先放置文件,然后再获取body,因此在提交表单时,上传的文件之后是名称。 我在文档t.ly/dyp9中找到了答案,输入名称也可以使用,因此我获取输入值,然后将其传递给dom中上传的文件的输入名称,以下是代码

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, path);
  },
  filename: function (req, file, cb) {
    cb(null, file.filename) 
  }
})
<form action="/upload" method="POST" enctype= "multipart/form-data">
  <input type="text" name="fname">
  <input type="file" name="pic">
  <button onclick="submit()" >click me</button>
</form>
<script>
const submit = () => {
  const inputName = document.getElementsByTagName("input")[0].value;
  const pic = document.getElementsByTagName("input")[1];
  pic.name = inputName;
  const form = document.getElementsByTagName("form")[0].submit
  };
</script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接