如何访问 form.Parse 中的字段和文件 强大库的解析

how to access fields and files in form.parse of formidable library

提问人:Omid Azad 提问时间:9/12/2023 更新时间:9/12/2023 访问量:42

问:

我写了一个这样的文件上传处理程序来获取用户头像以及用户名等用户信息来注册新用户

const fs = require('fs');
const path = require('path');
const formidable = require('formidable');
const { getFieldsAndFiles } = require('../controllers/userAuth');

const checkFileType = (file) => {
  const type = file[0].mimetype.split('/').pop();
  const validTypes = ['png', 'jpeg', 'jpg'];
  if (validTypes.indexOf(type) == -1) {
    console.log('The file type is invalid');
    return false;
  }
  return true;
}

const uploadAvatar = async (req, res, next) => {
  // console.log(req.body);
  const form = new formidable.IncomingForm();
  const uploadsFolder = path.join(__dirname, '../uploads/avatars');
  form.multiples = true;
  form.maxFileSize = 50 * 1024 * 1024; //50 MB
  form.uploadDir = uploadsFolder;
  form.parse(req, async (error, fields, files) => {

    getFieldsAndFiles(fields, files);

    if (error) {
      console.log(error, 'Error parsing files');
      return res.json({ok: false, msg: 'Error parsing files'})
    };

    if (files.avatar) {
      const file = files.avatar
      const isValid = checkFileType(file);
      const fileName = encodeURIComponent(file[0].originalFilename.replace(/&. *;+/g, '-'))
      console.log('file name is: ', fileName);
      if (!isValid) {
        return res.json({ok: false, msg: 'File type is invalid'})
      }
      try {
        console.log('file path is: ', file[0].filepath );
        fs.rename(file[0].filepath, path.join(uploadsFolder, fileName), (error) => {
          if (error) {
            console.log('file upload failed:', error);
            // Handle the error and return an appropriate response
            return res.json({ ok: false, msg: 'Upload failed' });
          }
          // File renamed successfully, continue with the rest of the code
        });

      } catch (error) {
        console.log(error, 'file upload failed, trying to remove the temp file...');
        try { fs.unlink(file[0].path) } catch (error) { };
        return res.json({ ok: false, msg: 'Upload failed' });
      }
    } else if(files.files instanceof Array && files.files.length > 0) {
    } else {
      return res.json({ ok: false, msg: 'No files uploaded' });
    }
    // return res.status(200).json({ ok: true, msg: 'File uploaded successfuly' })
  })
  next()
}

module.exports = uploadAvatar ;

我需要从回调函数中提取和导出字段和文件值,以便在控制器文件中的注册函数中使用它。我在控制器文件中创建了一个名为函数的函数,并在这个强大的文件中调用它以将字段和文件传递给它。 这是控制器文件form.parsegetFieldsAndFiles

const UserModel = require('../models/UserModel');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const dotenv = require('dotenv');

dotenv.config();
const secretKey = process.env.SEC_KEY;
const createToken = function (_id) {
  return jwt.sign({ _id }, secretKey, { expiresIn: '1d' })
};

let username;
let email;
let password;
let firstName;
let lastName;
let birthDate;
let phoneNumber;
let avatar;
let avatarPath;

const getFieldsAndFiles = async (fields, files) => {
  username = fields.username[0].trimLeft();
  email = fields.email[0].trimLeft();
  password = fields.password[0].trimLeft();
  firstName = fields.firstName[0].trimLeft();
  lastName = fields.lastName[0].trimLeft();
  birthDate = fields.birthDate[0].trimLeft();
  phoneNumber = fields.phoneNumber[0].trimLeft();
  avatar = files.avatar[0]
  avatarPath = avatar.filepath
  console.log('username in getFieldsAndFiles:', username);
  console.log('avatar path getFieldsAndFiles:', avatarPath);
};

const signupUser = async (req, res) => {
  console.log('begining of controller');
  console.log('username in signup function:', username);
  
  try {
    const usernameExists = await UserModel.findOne({ username });
    if (usernameExists) return (res.status(400).json({ error: 'Username is already in use.' }));

    const emailExists = await UserModel.findOne({ email });
    if (emailExists) return (res.status(400).json({ error: 'Email is already in use.' }));

    if (password.length < 8) return (res.status(400).json({ error: 'Password is not strong enough.' }));

    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(password, salt);

    const newUser = await UserModel.create({
      username,
      firstName,
      lastName,
      email,
      password: hashedPassword,
      friends,
      birthDate,
      avatar: avatarPath,
      phoneNumber,
      city,
      status,
      occupation,
      education,
      location,
      bio,
      gender
    })
    const token = createToken(newUser._id);
    console.log(newUser);
    res.status(201).json({ newUser, token });

  } catch (error) {
    res.status(500).json({ error: error.message })
  }
};

const signinUser = async (req, res) => {
  try {
    const { username, password } = req.body;
    const user = await UserModel.findOne({ username });
    console.log(user);
    const token = createToken(user._id);
    if (!user) return (res.status(400).json({ error: "User does not exist." }));
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) return (res.status(400).json({ error: "Invalid credentials." }));
    res.status(200).json({ user, token });

  } catch (error) {
    res.status(400).json({ error: error.message });
  };
};

module.exports = {
  signupUser,
  signinUser,
  getFieldsAndFiles
}

但是范围和所有这些东西都不允许我在注册函数中使用这些提取的用户信息值来保存新用户注册。

我对代码中的任何更改都完全开放,因此我可以访问包含用户信息和上传文件的 formData 文本的字段和文件。

PS:由于formData,没有req.body或req.file

JavaScript 节点 .js 范围 多部分表单数据 强大

评论


答: 暂无答案