简体   繁体   English

没有在 req.body Express/node.js 中获取表单数据

[英]Not getting form data in req.body Express/node.js

I am trying to create e registration for a new user with profile picture upload.我正在尝试通过个人资料图片上传为新用户创建电子注册。 But my form data is not passing to the route.但是我的表单数据没有传递给路由。 I have added body-parser middleware but still, it seems something is wrong and I cannot find the reason.我添加了 body-parser 中间件,但似乎有问题,我找不到原因。

Error:错误:

D:\temp_project\smpms\routes\users.js:118
                        if (err) throw err;
                                 ^

Error: Illegal arguments: undefined, string
    at _async (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:214:46)
    at Object.bcrypt.hash (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:220:13)
    at D:\temp_project\smpms\routes\users.js:117:28
    at Immediate.<anonymous> (D:\temp_project\smpms\node_modules\bcryptjs\dist\bcrypt.js:153:21)
    at processImmediate (internal/timers.js:456:21)
[nodemon] app crashed - waiting for file changes before starting...

app.js应用程序.js

const express = require("express");
const expressLayouts = require("express-ejs-layouts");
const mongoose = require("mongoose");
const passport = require("passport");
const flash = require("connect-flash");
const session = require("express-session");
const multer = require('multer');
const path = require('path');
var dotenv = require('dotenv').config();
const bodyParser =  require('body-parser');
const app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
app.use(express.static("public"));

// Passport Config
require("./config/passport")(passport);

// DB Config
const db = require("./config/keys").mongoURI;

// Connect to MongoDB
mongoose
  .connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log("MongoDB Connected"))
  .catch((err) => console.log(err));

// EJS
app.use(expressLayouts);
app.set("view engine", "ejs");

// Express body parser
app.use(express.urlencoded({ extended: true }));

// Express session
app.use(
  session({
    secret: "secret",
    resave: true,
    saveUninitialized: true,
  })
);

// Passport middleware
app.use(passport.initialize());
app.use(passport.session());

// Connect flash
app.use(flash());

// Global variables
app.use(function (req, res, next) {
  res.locals.success_msg = req.flash("success_msg");
  res.locals.error_msg = req.flash("error_msg");
  res.locals.error = req.flash("error");
  next();
});

// Routes
app.use("/", require("./routes/index.js"));
app.use("/users", require("./routes/users.js"));

const PORT = process.env.PORT || 5000;

app.listen(PORT, console.log(`Server started on port ${PORT}`));

User.js - User model User.js - 用户 model

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  avatar:{
    type:String,
    required:true
  },
  date: {
    type: Date,
    default: Date.now
  }
});

const User = mongoose.model('User', UserSchema);

module.exports = User;

User.js route: User.js 路由:

const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const passport = require("passport");
const multer = require('multer');
const path = require('path');
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
// Load User model
const User = require("../models/User");
const {forwardAuthenticated} = require("../config/auth");


// Login Page
router.get("/login", forwardAuthenticated, (req, res) => {
    res.render("login", {title: "Login", layout: "layout"});
});

// Register Page
router.get("/register", forwardAuthenticated, (req, res) => {
    res.render("register", {title: "Register", layout: "layout"});
});

// Register
router.post("/register", (req, res) => {
    //const {name, email, password, password2||avatar} = req.body;
    const name = req.body.name
    const email = req.body.email
    const password = req.body.password;
    const password2 = req.body.password2;
    const avatar = req.body.avatar;

    let errors = [];
    //
    // if (!name || !email || !password || !password2) {
    //     errors.push({msg: "Please enter all fields"});
    // }
    // if (password && password.length < 6) {
    //     errors.push({msg: "Password must be at least 6 characters"});
    // }
    // if (password != password2) {
    //     errors.push({msg: "Passwords do not match"});
    // }

    if (errors.length > 0) {
        res.render("register", {
            errors,
            name,
            email,
            password,
            password2,
            title: "Register",
            layout: "Layout",
        });
    } else {
        User.findOne({email: email}).then((user) => {
            if (user) {
                errors.push({msg: "Email already exists"});
                res.render("register", {
                    errors,
                    name,
                    email,
                    password,
                    password2,
                    title: "Register",
                    layout: "Layout",
                });
            } else {
                const newUser = new User({
                    name,
                    email,
                    password,
                });
                //Set The Storage Engine
                const storage = multer.diskStorage({
                    destination: './public/uploads/',
                    filename: function (req, file, cb) {
                        cb(null, file.fieldname + '-' + newUser._id + path.extname(file.originalname));
                    }
                });

                // Init Upload
                const upload = multer({
                    storage: storage,
                    limits: {fileSize: 1000000},
                    fileFilter: function (req, file, cb) {
                        checkFileType(file, cb);
                    }
                }).single('avatar');

                // Check File Type
                function checkFileType(file, cb) {
                    // Allowed ext
                    const filetypes = /jpeg|jpg|png|gif/;
                    // Check ext
                    const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
                    // Check mime
                    const mimetype = filetypes.test(file.mimetype);

                    if (mimetype && extname) {
                        return cb(null, true);
                    } else {
                        cb('Error: Images Only!');
                    }
                }


                console.log(newUser);
                newUser.avatar = storage;
                console.log(newUser);
                bcrypt.genSalt(10, (err, salt) => {
                    bcrypt.hash(newUser.password, salt, (err, hash) => {
                        if (err) throw err;
                        newUser.password = hash;
                        newUser
                            .save()
                            .then((user) => {
                                req.flash(
                                    "success_msg",
                                    "You are now registered and can log in"
                                );
                                res.redirect("/users/login");
                            })
                            .catch((err) => console.log(err));
                    });
                });
            }
        });
    }
});

// Login
router.post("/login", (req, res, next) => {
    passport.authenticate("local", {
        successRedirect: "/dashboard",
        failureRedirect: "/users/login",
        failureFlash: true,
    })(req, res, next);
});

// Logout
router.get("/logout", (req, res) => {
    req.logout();
    req.flash("success_msg", "You are logged out");
    res.redirect("/users/login");
});

module.exports = router;

Register.ejs is the file where the form is not passing data to the route. Register.ejs 是表单未将数据传递给路由的文件。

<div class="row mt-5">
  <div class="col-md-6 m-auto">
    <div class="card card-body">
      <h1 class="text-center mb-3">
        <i class="fas fa-user-plus"></i> Register
      </h1>
      <% include ./partials/messages %>
      <%= typeof msg != 'undefined' ? msg : '' %>
      <form action="/users/register" method="POST" enctype="multipart/form-data">
        <div class="form-group">
          <label for="name">Name</label>
          <input
            type="name"
            id="name"
            name="name"
            class="form-control"
            placeholder="Enter Name"
            value="<%= typeof name != 'undefined' ? name : '' %>"
          />
        </div>
        <div class="form-group">
          <label for="email">Email</label>
          <input
            type="email"
            id="email"
            name="email"
            class="form-control"
            placeholder="Enter Email"
            value="<%= typeof email != 'undefined' ? email : '' %>"
          />
        </div>
        <div class="form-group">
          <label for="password">Password</label>
          <input
            type="password"
            id="password"
            name="password"
            class="form-control"
            placeholder="Create Password"
            value="<%= typeof password != 'undefined' ? password : '' %>"
          />
        </div>
        <div class="form-group">
          <label for="password2">Confirm Password</label>
          <input
            type="password"
            id="password2"
            name="password2"
            class="form-control"
            placeholder="Confirm Password"
            value="<%= typeof password2 != 'undefined' ? password2 : '' %>"
          />
        </div>
        <div class="form-group">
          <label for="">Profile Picture</label>
          <input type="file" name="avatar" id="" class="form-control  file-path validate">
        </div>
        <button type="submit" class="btn btn-primary btn-block">
          Register
        </button>
      </form>
      <p class="lead mt-4">Have An Account? <a href="/users/login">Login</a></p>
    </div>
  </div>
</div>

It seems that you aren't using multer correctly.看来您没有正确使用multer Usually multer configuration is set globally and above all the APIs and then we pass that middleware function generated by multer to that specific API which has multipart/form-data header in its request.通常multer配置是全局设置的,尤其是所有 API,然后我们将 multer 生成的中间件multer给特定的 API,该 API 在其请求中包含multipart/form-data Z099FB995346F31C7549F6E40A94F3 You have to move your configuration for multer , outside of your API, then pass the upload as a middleware to your API.您必须将 multer 的配置multer之外,然后将upload作为中间件传递给 API。 Also from your clientside, you have to pass data properly.同样从您的客户端,您必须正确传递数据。 A good answer about sending JSON alongside the File with FormData object can be found here .可以在此处找到有关将 JSON 与带有FormData object 的文件一起发送的一个很好的答案。 Also you can add text fields in FormData object from clientside and receive it as object in req.body according to multer documentation.您还可以从客户端在 FormData object 中添加文本字段,并根据multer文档在req.body其作为 object 接收。 Just make sure you're passing data from clientside to server correctly.只要确保您正确地将数据从客户端传递到服务器。 Here is your router with multer middleware:这是带有multer中间件的路由器:

const express = require("express");
const router = express.Router();
const fs = require('fs');
const bcrypt = require("bcryptjs");
const passport = require("passport");
const multer = require('multer');
const path = require('path');
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
// Load User model
const User = require("../models/User");
const { forwardAuthenticated } = require("../config/auth");


// Login Page
router.get("/login", forwardAuthenticated, (req, res) => {
    res.render("login", { title: "Login", layout: "layout" });
});

// Register Page
router.get("/register", forwardAuthenticated, (req, res) => {
    res.render("register", { title: "Register", layout: "layout" });
});

const storage = multer.diskStorage({
    destination: './public/uploads/'
});

// Init Upload
const upload = multer({
    storage: storage,
    limits: { fileSize: 1000000 },
    fileFilter: function (req, file, cb) {
        checkFileType(file, cb);
    }
});

// Check File Type
function checkFileType(file, cb) {
    // Allowed ext
    const filetypes = /jpeg|jpg|png|gif/;
    // Check ext
    const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
    // Check mime
    const mimetype = filetypes.test(file.mimetype);

    if (mimetype && extname) {
        return cb(null, true);
    } else {
        cb('Error: Images Only!');
    }
}
// Register
router.post("/register", upload.single('avatar'), (req, res) => {
    //const {name, email, password, password2||avatar} = req.body;
    const name = req.body.name
    const email = req.body.email
    const password = req.body.password;
    const password2 = req.body.password2;


    let errors = [];
    //
    // if (!name || !email || !password || !password2) {
    //     errors.push({msg: "Please enter all fields"});
    // }
    // if (password && password.length < 6) {
    //     errors.push({msg: "Password must be at least 6 characters"});
    // }
    // if (password != password2) {
    //     errors.push({msg: "Passwords do not match"});
    // }

    if (errors.length > 0) {
        res.render("register", {
            errors,
            name,
            email,
            password,
            password2,
            title: "Register",
            layout: "Layout",
        });
    } else {
        User.findOne({ email: email }).then((user) => {
            if (user) {
                errors.push({ msg: "Email already exists" });
                res.render("register", {
                    errors,
                    name,
                    email,
                    password,
                    password2,
                    title: "Register",
                    layout: "Layout",
                });
            } else {
                const directory = "/images/";
                const newUser = new User({
                    name,
                    email,
                    password,
                    avatar: `./public/uploads/${req.file}`
                });
                const filePath = path.join(__dirname, "../public/uploads/");
                fs.rename(filePath + req.file.filename, req.file.fieldname + '-' + newUser._id + path.extname(req.file.originalname), (error) => {
                    if (error) {
                        return console.log(`Error: ${error}`);
                    }
                });
                newUser.avatar = 'public/uploads/' + req.file.fieldname + '-' + newUser._id + path.extname(req.file.originalname);
                console.log(newUser);
                bcrypt.genSalt(10, (err, salt) => {
                    bcrypt.hash(newUser.password, salt, (err, hash) => {
                        if (err) throw err;
                        newUser.password = hash;
                        newUser
                            .save()
                            .then((user) => {
                                req.flash(
                                    "success_msg",
                                    "You are now registered and can log in"
                                );
                                res.redirect("/users/login");
                            })
                            .catch((err) => console.log(err));
                    });
                });
            }
        });
    }
});

// Login
router.post("/login", (req, res, next) => {
    passport.authenticate("local", {
        successRedirect: "/dashboard",
        failureRedirect: "/users/login",
        failureFlash: true,
    })(req, res, next);
});

// Logout
router.get("/logout", (req, res) => {
    req.logout();
    req.flash("success_msg", "You are logged out");
    res.redirect("/users/login");
});

module.exports = router;

It will save your file without any problem (if your configuration about directory and filename was okay).它会毫无问题地保存您的文件(如果您的目录和文件名配置没问题)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM