问题
As the title suggests, I am getting error: {"message": "ENOENT: no such file or directory, open 'E:\\astrology\\utils\\uploads\\1600798534862qf.png'"}
in my project even after passing every required configs.
Note: I've divided 'app' into two parts: main 'app.js' and 'appRoute.js' for more dynamic and code clarity.
app.js
const express = require("express");
const path = require("path");
const app = express();
const directory = path.join(__dirname, "utils/uploads");
app.use("/uploads", express.static(directory));
require("./config/database/db")();
require("./config/approutes/appRoutes")(app);
module.exports = app;
appRoute.js
require("dotenv").config();
const morgan = require("morgan");
const bodyParser = require("body-parser");
const cors = require("cors");
const productRoutes = require("../../api/routes/products");
module.exports = function (app) {
app.use(morgan("dev"));
app.use(bodyParser.urlencoded({ extended: true, limit: "100mb" }));
app.use(bodyParser.json());
app.use(cors({ credentials: true, origin: true }));
app.use("/products", productRoutes);
app.use((req, res, next) => {
const error = new Error("Not found");
error.status = 404;
next(error);
});
app.use((error, req, res, next) => {
console.log('SHOW ERROR', error);
res.status(error.status || 500);
res.json({
error: {
message: error.message,
},
});
});
};
fileUpload.js
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, __dirname + "/uploads");
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname.replace(/\s+/g, "-"));
},
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
fileFilter: fileFilter,
});
module.exports = upload;
Product.js (controller)
exports.create_product = async (req, res, next) => {
const { title, min_content, content } = req.body;
console.log("req files", req.files);
try {
const product = new Product({
title,
min_content,
content,
});
const new_product = await product.save();
console.log("error caught", new_product);
if (new_product) {
res.status(201).json({ msg: "New product added", new_product });
} else {
res.status(400).json({ msg: "Unable to create new product" });
}
} catch (error) {
res.status(500).json({ msg: "Internal server error", error });
}
};
Product.js (route)
const express = require("express");
const router = express.Router();
const ProductController = require("../controllers/products");
const uploadMW = require("../middleware/fileUpload");
router.get("/all", ProductController.get_products);
router.post("/new", uploadMW.fields([{ name: "thumbnail" }, { name: "image" }]), ProductController.create_product
);
module.exports = router;
Directory structure
My OS is windows, so I have included the config to replace the (:) from file names, but nothing seems to work for me. Any help to resolve the same is appreciated.
回答1:
Your directory structures look messed up.
Your uploads
directory in fileUpload.js
is referring to a directory in ./api/middleware/uploads
when it should be referencing ./utils/uploads
(the paths relative to the module are incorrect).
// fileUpload.js
const multer = require("multer");
const path = require("path");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.resolve(__dirname, `..${path.sep}..${path.sep}`, `${path.sep}utils${path.sep}uploads`);
},
__dirname
returns the directory that the current file is in. So in this case it will be middleware
. (I am deducing this based on the require in your Product.js
file).
Try fixing the path to the uploads
directory in the fileUpload.js
by pointing at the same directory that the static files are being served from.
Also, I seen in the chat that Arya
started with you that you are now managing to get it working on a *nix OS but not on windows.
Try changing your path separators to use path.sep
from the path
module. Arya
's solution above looks good, i.e. the file paths now all look fixed relative to the static uploads
directory. I have updated my answer to use path.sep based on the original code that you published and the directory structure that you provided.
回答2:
app.js file will be like this
// modules =================================================
var express = require('express');
var app = express();
const logger = require('morgan');
var bodyParser = require('body-parser');
const indexRouter = require("./routes/index");
const cors = require('cors');
const path = require("path");
config = require("./environments/index");
var http = require('http').Server(app);
// configuration ===========================================
var port = config.PORT || 8081; // set our port
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true,
parameterLimit: 50000
}));
app.use(cors());
app.use(logger('dev'))
app.use("/api", indexRouter);
app.use(express.static(path.join(__dirname, "/build")));
http.listen(port, () => {
console.log('Magic happens on port ' + port); // shoutout to the user
});
exports = module.exports = app;
create multerhelper.js file in your app nd add below code in it
const multer = require('multer');
// const fs = require('fs');
let fs = require('fs-extra');
let storage = multer.diskStorage({
destination: function (req, file, cb) {
let path = `/uploads`;
fs.mkdirsSync(path);
cb(null, __dirname + path);
},
filename: function (req, file, cb) {
// console.log(file);
cb(null, Date.now() + file.originalname.replace(/\s+/g, "-"));
}
})
var upload = multer({ storage: storage });
let createUserImage = upload.single('images');
let multerHelper = {
createUserImage,
}
module.exports = multerHelper;
In your product.js
(route) file import this file
const multerhelper = require("../multerhelper.js");
router.post("/new",multerhelper.createUserImage,ProductController.
create_product);
回答3:
Finally I was able to resolve this. I am posting the solution if anyone comes across the same issue (Windows OS to be specific), this will surely help.
I changed my directory structure by shifting the uploads
folder directly outside instead of /utils/uploads
(for the sake of easeness) & made a minor change in fileUpload.js:
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, process.cwd() + "/uploads/");
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname.replace(/\s+/g, "-"));
},
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
fileFilter: fileFilter,
});
module.exports = upload;
Instead of using __dirname
, I replaced it with process.cwd()
, and appended my target folder :
destination: function (req, file, cb) {
cb(null, process.cwd() + "/uploads/");
},
Reference: What's the difference between process.cwd() vs __dirname?
P.S. Thanks to @jeeves & @Arya for their thorough suggestions :)
来源:https://stackoverflow.com/questions/64015633/message-enoent-no-such-file-or-directory-open-e-astrology-utils-uploa