"message": "ENOENT: no such file or directory, open 'E:\astrology\utils\uploads\1600798534862qf.png'"

"message": "ENOENT: no such file or directory, open 'E:\\astrology\\utils\\uploads\\1600798534862qf.png'"

正如标题所暗示的,即使在通过了所有必需的配置后,我的项目中仍然 error: {"message": "ENOENT: no such file or directory, open 'E:\astrology\utils\uploads\1600798534862qf.png'"}

注意:我将 'app' 分为两部分:主要 'app.js' 和 'appRoute.js' 以获得更多动态和代码清晰度。

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(控制器)

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(路线)

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;

目录结构

我的 OS 是 windows,所以我包含了替换文件名中的 (:) 的配置,但似乎对我没有任何作用。任何帮助解决同样的问题表示赞赏。

app.js 文件会像这样

// 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;

在您的应用程序中创建 multerhelper.js 文件并在其中添加以下代码

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;

在您的 product.js(路线)文件中导入此文件

  const multerhelper = require("../multerhelper.js");  
  router.post("/new",multerhelper.createUserImage,ProductController.
  create_product);

您的目录结构看起来一团糟。 fileUpload.js 中的 uploads 目录 指的是 ./api/middleware/uploads 中的目录,而它应该引用 ./utils/uploads(相对于模块的路径不正确)。

// 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 当前文件所在的目录。所以在这种情况下它将是 middleware。 (我是根据您的 Product.js 文件中的要求推断的)。

尝试通过指向提供静态文件的相同目录来修复 fileUpload.jsuploads 目录的路径。

此外,我在聊天中看到 Arya 开始与您合作,您现在设法让它在 *nix OS 上运行,但在 windows 上却不行。

尝试更改路径分隔符以使用 path 模块中的 path.sepArya 上面的解决方案看起来不错,即文件路径现在看起来都相对于静态 uploads 目录是固定的。我已经根据您发布的原始代码和您提供的目录结构更新了我的答案以使用 path.sep。

我终于解决了这个问题。如果有人遇到同样的问题(Windows OS 具体来说),我会发布解决方案,这肯定会有所帮助。

我更改了我的目录结构,将 uploads 文件夹直接移到外面而不是 /utils/uploads(为了方便起见)并对 [=31= 做了一个小改动]:

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;

我没有使用 __dirname,而是将其替换为 process.cwd(),并附加了我的目标文件夹:

destination: function (req, file, cb) {
    cb(null, process.cwd() + "/uploads/");
  },

参考What's the difference between process.cwd() vs __dirname?

P.S。感谢@jeeves 和@Arya 的全面建议:)