2

我在使用节点 16 和 ES6 时遇到问题。我正在尝试制作一个上传文件控制器,但我遇到了未定义的 req.file.stream 我正在使用 multer 来处理上传文件。

第一个问题是 __dirname undefined,我可以使用路径和新 URL 来修复它。

我在管道中遇到的错误

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

TypeError [ERR_INVALID_ARG_TYPE]: The "source" argument must be of type function or an instance of Stream, Iterable, or AsyncIterable. Received undefined

我的 userRoutes.js

import express from "express";
import { signin, signup, logout } from "../Controller/AuthController.js";
import {
  getUsers,
  getUser,
  updateUser,
  deleteUser,
  follow,
  unfollow,
} from "../Controller/UserController.js";
import { upload } from "../Controller/UploadController.js";
import multer from "multer";

const router = express.Router();
// Auth
router.post("/signin", signin);
router.post("/signup", signup);
router.post("/logout", logout);

// users
router.get("/", getUsers);
router.get("/:id", getUser);
router.patch("/:id", updateUser);
router.delete("/:id", deleteUser);
router.patch("/follow/:id", follow);
router.patch("/unfollow/:id", unfollow);

// upload
router.post("/upload", multer().single("file"), upload);
export default router;

还有我的 UploadController.js


import fs from "fs";
import { promisify } from "util";
import stream from "stream";

const pipeline = promisify(stream.pipeline);
// const { uploadErrors } = require("../utils/errors.utils");
import path from "path";
const __dirname = path.dirname(new URL(import.meta.url).pathname);

export const upload = async (req, res) => {
  try {
    // console.log(req.file);
    console.log(__dirname);
    if (
      !req.file.mimetype == "image/jpg" ||
      !req.file.mimetype == "image/png" ||
      !req.file.mimetype == "image/jpeg"
    )
      throw Error("invalid file");

    if (req.file.size > 2818128) throw Error("max size");
  } catch (err) {
    const errors = uploadErrors(err);
    return res.status(201).json({ err });
  }
  const fileName = req.body.name + ".jpg";
  await pipeline(
    req.file.stream,
    fs.createWriteStream(
      `${__dirname}/../client/public/uploads/profil/${fileName}`
    )
  );

  try {
    await User.findByIdAndUpdate(
      req.body.userId,
      { $set: { picture: "./uploads/profil/" + fileName } },
      { new: true, upsert: true, setDefaultsOnInsert: true },
      (err, docs) => {
        if (!err) return res.send(docs);
        else return res.status(500).send({ message: err });
      }
    );
  } catch (err) {
    return res.status(500).send({ message: err });
  }
};
4

2 回答 2

1

Multer 将文件作为缓冲区而不是流提供给您。req.file.stream不是有效属性,而是req.file.bufferhttps://github.com/expressjs/multer#file-information

从代码的外观来看,您正在尝试将文件保存在磁盘上。您可以为此使用multer DiskStorage。创建一个存储实例并将其作为配置传递给 multer 实例:

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, `${__dirname}/../client/public/uploads/profil/`);
  },
  filename: function (req, file, cb) {
    cb(null, req.body.name + '.jpg');
  },
});

const upload = multer({ storage });

router.post('/upload', upload.single('file'), upload);

查看 Node.js 指南中的免费请求解析,了解如何在 Node.js中处理文件上传。

于 2021-06-01T14:29:02.480 回答
1

如果你想使用req.file.stream,你需要安装这个版本的 multer:

npm install --save multer@^2.0.0-rc.1

并且您的代码将完美运行,只需将您的代码更改req.file.mimetypereq.file.detectedMimeType!!

于 2021-12-28T00:04:39.303 回答