expressjs / multer

Node.js middleware for handling `multipart/form-data`.
MIT License
11.61k stars 1.06k forks source link

How can I get other form keys in req.body before multer processing file? #1201

Open ChaseWindYoungs opened 1 year ago

ChaseWindYoungs commented 1 year ago

First, I want use multer in a single router, and this request‘s data not only a file, but also include other form data, these are part of important code

const bodyParser = require("body-parser");
const staticPath = path.join(__dirname, "..", "static");
const urlencodedParser = bodyParser.urlencoded({ extended: false }); // create application/json parser

const multerStorage = multer.diskStorage({
  destination: function (req, file, cb) {
    try {
      if (!fs.existsSync(path.join(staticPath, "cache"))) {
        fs.mkdirSync(path.join(staticPath, "cache"));
      }
      cb(null, path.join(staticPath, "cache"));
    } catch (error) {
      console.log("destination = error ======>", error);
    }
  },
  filename: async (req, file, cb) => {
    try {
      console.log('req.body =============>', req.body.fileMD5)
      console.log("file ====> ", file);
      const { fieldname, originalname, mimetype } = file;
      let fileFormat = originalname.split(".");
      const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
      cb(
        null,
        `${fieldname}-${uniqueSuffix}.${fileFormat[fileFormat.length - 1]}`
      );
    } catch (error) {
      console.log("filename = error ======>", error);
    }
  },
});
const uploadCache = multer({ storage: multerStorage });

router.post("/sliceFile", urlencodedParser, uploadCache.single("file"), (req, res) => {
  console.log('urlencodedParser =====> ',req.body);
  try {
    res.send({
      code: 200,
      message: "test",
    });
  } catch (error) {
    console.log(error);
  }
});

module.exports = router;

before uploadCache.single("file"), I want use urlencodedParser to processing form‘s fileMD5, used as a filename to save a file , but I can't get any in rer.body during multerStorage, can you tell me how to use form other data during multerStorage handle file

ChaseWindYoungs commented 1 year ago

by the way, is chatGPT told me to use body-parser

jsdev903 commented 1 year ago

You will need to use req.query passing query parameters from browser context

//in Browser Context
async function uploadFile(file, fileType, index) {
    const fileName = `${fileType}${index}`;
    const formData = new FormData();
    formData.append('file', file);
    const response = await fetch(`/api/upload?filename=${encodeURIComponent(fileName)}`, { method: 'POST', body: formData });
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    return response.json();
}

//in NodeJS
const uploadFiles = async (req, res) => {
    console.log(req.query.filename)
    const upload = multer({
        storage: multer.diskStorage({
            destination: 'uploads/',
            filename: (req, file, cb) => cb(null, `${req.query.filename}`)
        })
    });

    upload.single('file')(req, res, (err) => {
        if (err) return res.send(err);
        console.log(`Received file ${req.query.filename}`);
        res.json({ status: 'OK', filename: req.file.originalname });
    });
}