ExpressJS报Cannot POST /api/v1/users错误的原因排查
Express API POST请求报错"Cannot POST /api/v1/users"排查
我正在开发Express API,应用启动正常,但向http://localhost:3000/api/v1/users发送POST请求时,返回“Cannot POST /api/v1/users”错误。以下是相关代码,求错误原因及解决方法:
User.js(模型)
const mongoose = require('mongoose'); const userSchema = mongoose.Schema({ name: { type: String, required: true, min: 6, max: 255 }, email: { type: String, required: true, min: 6, max: 1024 }, password: { type: String, required: true, minlength: 6 }, subscribe: { type: Boolean, default: false }, date: { type: Date, default: Date.now }, role: { type: String, required: false, minlength: 4 }, address: { type: String, required: false, minlength: 4, defaultValue: "" }, nonce: { type: String, required: false, minlength: 4, defaultValue: "" }, }) module.exports = mongoose.model('User', userSchema);
user.js(控制器)
const Joi = require('@hapi/joi'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const nodemailer = require("nodemailer"); //models const User = require('../models/user'); const expired_token = require('../models/expired_token'); module.exports = { register: async (req, res) => { const schemaRegister = Joi.object({ name: Joi.string().min(3).max(255).required(), email: Joi.string().min(4).max(255).required().email(), password: Joi.string().min(6).max(1024).required() }) // validate user const { error } = schemaRegister.validate(req.body) if (error) { return res.status(400).json({ data: error, message: error.details[0].message, status: "error" }) } const isEmailExist = await User.findOne({ email: req.body.email }); if (isEmailExist) { return res.status(400).json({ data: "", message: "email already registered", status: "error" }) } // hash password const salt = await bcrypt.genSalt(10); const password = await bcrypt.hash(req.body.password, salt); const user = new User({ name: req.body.name, email: req.body.email, role: "user", password: password }); try { const savedUser = await user.save(); console.log(savedUser); const token = jwt.sign({ name: savedUser.name, id: savedUser._id, email: savedUser.email, role: savedUser.role }, process.env.TOKEN_SECRET); res.status(200).json({ data: { email:savedUser.email, name: savedUser.name, role: savedUser.role, token: token }, message:"Successful request", status: "success" }); } catch (error) { res.status(401).json({ data: error, message:"Error creating user", status: "error" }); } }, login: async (req, res) => { const schemaLogin = Joi.object({ email: Joi.string().min(6).max(255).required().email(), password: Joi.string().min(6).max(1024).required() }) const { error } = schemaLogin.validate(req.body); if (error) { return res.status(400).json({ data: error, message: error.details[0].message, status: "error" }) } const user = await User.findOne({ email: req.body.email }); if (!user) { return res.status(400).json({ data: "", message: "User not found", status: "error" }) } const validPassword = await bcrypt.compare(req.body.password, user.password); if (!validPassword) { return res.status(400).json({ data: {}, message: "Invalid password", status: "error" }) } const token = jwt.sign({ name: user.name, id: user._id, email: user.email, role: user.role }, process.env.TOKEN_SECRET); res.status(200).json({ data: { email:user.email, name: user.name, token: token }, message:"Successful request", status: "success" }); }, list_users: async (req, res) => { const users = await User.find({}); res.status(200).json({ data: users, message:"Successful request", status: "success" }); }, logout: async (req, res) => { let user_info = req.decoded; let token = req.token; const expired_token_exists = await expired_token.findOne({ token: token }); if (expired_token_exists) { return res.status(200).json({ data: "", message: "user already logged out", status: "success" }) } const data = new expired_token({ id_user: user_info.id, token: token }); try { const saved_expired_token = await data.save(); res.status(200).json({ data: saved_expired_token, message:"Successful request", status: "success" }); } catch (error) { res.status(401).json({ data: error, message:"Error creating user", status: "error" }); } }, get_user_data: async (req, res) => { let user_info = req.decoded; try { const user = await User.find({ _id:user_info.id }); const user_json=user[0]; const user_data = { id:user_info.id, name:user_json.name, email:user_json.email, subscribe:user_json.subscribe, role:user_json.role, date:user_json.date }; res.status(200).json({ data: user_data, message:"Successful request", status: "success" }); } catch (error) { res.status(401).json({ data: error, message:"Error getting user data", status: "error" }); } } }
routes/index.js
const { func } = require('@hapi/joi'); const controller = require('../../v1/controllers/users'); const verifyToken = require('../../v1/utils').verifyToken; module.exports = (router) => { router.route('/list_users') .get(verifyToken, controller.list_users); router.route('/register') .post(controller.register); router.route('/login') .post(controller.login); router.route('/logout') .post(verifyToken, controller.logout); router.route('/get_user_data') .get(verifyToken, controller.get_user_data); return router; }
入口文件index.js
let users = require('./v1/routes/users.js'); app.users('/api/v1/users', users(router));
错误原因及解决方法
1. 路由挂载方法错误
Express框架中不存在app.users()这个路由注册方法,正确的路由挂载方式应该使用app.use()。你使用了错误的方法名,导致用户模块的路由完全没有被注册到应用中,所以访问/api/v1/users时会出现找不到路由的错误。
2. 根路径未定义POST处理
你的用户子路由中,仅给/register、/login等子路径配置了POST方法,根路径/api/v1/users本身没有对应的POST路由处理逻辑。如果你的请求是直接发送到根路径而非具体子接口,也会触发该错误。
解决方案
方法一:修正路由挂载代码
将入口文件中的app.users()改为app.use():
let users = require('./v1/routes/users.js'); app.use('/api/v1/users', users(router));
方法二:调整请求目标路径
如果你的需求是调用用户注册接口,应该将POST请求发送到http://localhost:3000/api/v1/users/register,而非根路径/api/v1/users。
可选:给根路径添加POST处理(若有需求)
如果确实需要让根路径支持POST请求,可以在路由文件中添加对应的处理逻辑:
router.route('/') .post(controller.yourPostHandler); // 替换为你需要的处理函数
内容的提问来源于stack exchange,提问作者user18644175
相关产品推荐
相关产品推荐

