MEAN 项目 - Multer 弄乱了请求正文

问题描述 投票:0回答:1

我是 MEAN 堆栈的新手,我正在尝试创建登录和注册功能,其中注册包括个人资料照片上传。这就是我偶然发现 multer 库的方式。

总的来说,收集表单元素后,我将它们发送到后端,如下所示:

//login.component.ts login() 函数

login(): void {

  const form_data = new FormData();
  form_data.append("username", this.username);
  form_data.append("password", this.password);

  this.user_service.login(form_data).subscribe(
    user => {
      if (user != null) {
        localStorage.setItem("logged_user", JSON.stringify(user));
        alert("Success!");
      }
      else {
        alert("Wrong userame/password!");
      }
    }
  )
}

然后,我使用我的 user_service 发送登录请求:

constructor(private http: HttpClient) {}

login(form_data: FormData) {
   return this.http.post<User>("http://localhost:4000/users/login", form_data);
}

在服务器端,除了作为后端应用程序的入口点的 server.ts 和定义 UserModel 的 user.ts 之外,我创建了三个文件夹:

  1. 带有 upload.ts 文件的“中间件”:
import multer from "multer";

const storage = multer.diskStorage({
    destination: '../frontend/src/assets/profile_photos',
    filename: (req, file, cb) => {
      cb(null, file.originalname);   

    },
});
  
const upload = multer({ storage: storage });

export default upload;
  1. 带有 user.controller.ts 文件的“控制器”:
import express from "express";

import UserModel from "../models/user"; 

export class UserController {
    
    login = async (req: express.Request, res: express.Response) => {
        
        // some login logic
        
    }
    
    register = async (req: express.Request, res: express.Response) => {
        
        // some register logic
        
    }
    
}
  1. 带有 user.router.ts 文件的“路由器”:
import express from "express";
import { UserController } from "../controllers/user.controller";
import upload from "../middlewares/upload";

const user_router = express.Router();

user_router.route("/login").post(
    (req, res) => new UserController().login(req, res)
)

user_router.route("/register").post(
    // ####
    upload.single('profile_photo_object'),
    (req, res) => new UserController().register(req, res)
)

export default user_router;

现在的问题是,无论我在请求正文中发送什么内容,当我进入login()函数时,request.body都是空的(我在控制台中从FormData对象打印了req.body.username和其他字段)。

当涉及到 register() 函数时,req.body 包含了我需要的所有内容,并且只要 #### 注释后面的行存在,就能按预期工作(甚至图像文件已成功上传)。如果我评论该行 (upload.single('profile_photo_object')),request.body 在 register() 中也会变为空。

我从中得出的唯一结论是,multer 在某种程度上影响了请求主体,但我不知道到底是如何以及为什么,因为我是 multer 的新手,并且我在互联网上找到了放在“中间件”中的代码。

有谁知道问题是什么以及如何修复它以保留图像上传功能并访问请求正文对象?

我测试了前端的所有内容,并且我发送到后端的 FormData 对象始终按照它们假设的方式进行初始化。

node.js mean multer
1个回答
0
投票

登录路由的问题是,当你发送表单数据时,请求是用

multipart/form-data
编码发送的,并且你没有使用任何中间件,即该路由上的multer,这就是为什么body是空的,这就是为什么另一方面,注册正在工作。

所以,你有两个选择: 不要在登录路由上使用表单数据,或者使用表单数据并添加 multer 中间件来处理请求:

// 1. don't use formdata, use json (also make sure you use json middleware)

login(): void {

  this.user_service.login({this.username, this.password}).subscribe(

// server
app.use(express.json());
// 2. mount multer middleware (use .none() to exclude files)

user_router.route("/login").post(
    upload.none(),
    (req, res) => new UserController().login(req, res)  
© www.soinside.com 2019 - 2024. All rights reserved.