expressjs / multer

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

Can't write file into folder on win10 using multer #507

Open shenmiweiyi opened 7 years ago

shenmiweiyi commented 7 years ago

I use multer upload file in express,But after upload controller js action,then local folder haven't upload file on win10. This is code. The upload form also set enctype="multipart/form-data".

This is upload.js.

var multer = require('multer'), mkdirp = require('mkdirp');

var storage = multer.diskStorage({ destination: function(req, file, cb) { var curCatalog = req.baseUrl.match(/admin\/([a-z]*)/)[1]; mkdirp('./public/upload/image/' + curCatalog, function(err) { if (err) { console.log(err); return; } }) cb(null, './public/upload/image/' + curCatalog + '/'); }, filename: function(req, file, cb) { var fileFormat = (file.originalname).split("."); cb(null, fileFormat[0] + "." + fileFormat[fileFormat.length - 1]); } });

var upload = multer({ storage: storage });

module.exports = upload;


This is upload controller javascript.

var async = require('async'), bcrypt = require('bcrypt-nodejs'), db = require('../../config/db'), product = require('../../models/product'), upload = require('../../utils/upload');

var uploadFile = upload.fields([{ name: 'pictures', maxCount: 10 }]);

module.exports = {

addProduct: function(req, res, next) { uploadFile(req, res, function(err) { var picturesDest = '', picturesPath = '', pctLength = req.files['pictures'].length;

        for(var i = 0; i < pctLength; i++){
            picturesDest = (req.files['pictures'][i].destination).replace(/^(\.\/public)/, '');
            picturesPath += picturesDest + req.files['pictures'][i].filename + ',';
        }

        picturesPath = picturesPath.substring(0, picturesPath.length-1);

        var productInfo = {
            title: req.body.title,
            pictures: picturesPath,
            description: req.body.description
        };

        db.getConnection(function(err, connection) {
            if (err) {
                throw err;
            }
            connection.query(product.insert, [productInfo.title, productInfo.pictures,productInfo.description], function(err, rows) {
                if (err) {
                    throw err;
                }
                res.redirect('/admin/product');
                connection.release();
            })
        })
    })
}

}

liguangsong commented 7 years ago

me too

fend25 commented 7 years ago

me too

Tritty commented 6 years ago

Me too. But I nocited that multer actually wrote the file into temp folder(for me, its 'C:\Users\myuser\AppData\Local\Temp'). It looks like the diskStorage function of multer didn't work. Breakpoints in Multer.diskStorage ({}) didn't hit.

jonchurch commented 4 years ago

In the code provided in OP's destination function, mkdirp likely won't complete before the cb is called for destination.

You can move the line cb(null, './public/upload/image/' + curCatalog + '/'); into the callback passed to mkdirp if you want to ensure the folder is created before returning the path from the destination function.

The destination function should look like this, to ensure that the folder is created before the path is passed to the cb of destination:

  function (req, file, cb) {
    const curCatalog = req.baseUrl.match(/admin\/([a - z]*)/)[1];
    mkdirp(`./public/upload/image/${curCatalog}`, function(err) {
      if (err) {
        console.log(err);
      } else {
        cb(null, `./public/upload/image/${curCatalog}/`);
      }
    });
  },

Please let me know if this helps! ❤️