使用Postman测试POST请求时404 Not Found问题排查与解决
Node.js+Express员工创建接口404排查方案
我在Node.js+Express项目中开发员工创建功能,已编写index.js、Employee Schema、Employee Controller及路由文件,项目运行在5001端口,测试POST请求URL为http://localhost:5001/create_employee,但Postman返回404 Not Found状态码。以下是排查方向和相关代码:
核心排查方向
- 路由未挂载到主应用:当前提供的
index.js完全没有引入员工路由,这是404最常见的原因。必须在主文件中导入并挂载路由。 - 端口配置不一致:确认
.env文件中的PORT是否设置为5001,或启动日志显示的端口是否确实为5001,避免请求端口错误。 - 路由路径拼写错误:确保请求URL的
/create_employee和路由中定义的路径完全一致,注意大小写、斜杠等细节。 - 文件路径导入错误:检查路由文件中导入控制器、控制器中导入模型的路径是否正确,避免因模块未加载导致路由失效。
相关代码
index.js
import express from "express" import bodyParser from "body-parser" import dotenv from "dotenv" import mongoose from 'mongoose' const app = express() app.use(bodyParser.json()) dotenv.config() const port = process.env.PORT || 5000 const mongo_url = process.env.MONGO_URL mongoose.connect(mongo_url).then(()=>{ console.log("Connected to database") app.listen(port,()=>{ console.log(`app is running on port: ${port}`) }) }).catch((err)=>{ console.error(`Error connecting to the database: ${err}`) })
Employee Schema
import mongoose from "mongoose" import validator from "validator" const employeeSchema = new mongoose.Schema({ nom:{type:String, required:[true,"Champ requis, veuillez le remplir"]}, prenom:{type:String, required:[true,"Champ requis veuillez le remplir"]}, email:{type:String, unique:true, required:[true,"Veuillez remplir votre email"], validate:function(v){if(!(validator.isEmail(v))){throw new Error("Email saisie est non valide")}}}, mot_de_passe:{type:String,required:[true,"Saisissez votre mot de passe"], minlength:8, maxlength:30, validate:function(v){if(this.mot_de_passe.length< 8 || this.mot_de_passe.length>30)throw new Error ("Mot de passe doit être entre 8 caractère et 30 caractères")}, validate:function(v){if(!(/[A-Z]/.test(v))) throw new Error("Mot de passe doit contenir au moins une lettre majuscule")}, validate:function(v){if(!(/[0-9]/.test(v))) throw new Error("Mot de passe doit contenir au moins un chiffre")}, validate:function(v){if(!(/[&#@{}-/*+=()"_'_]/.test(v)))throw new Error("Mot de passe doit contenir au moins l'un des symboles suivants:&#@{}-/*+=()'_")}}, date_naissance:{type:Date,required:[true,"Champ requis, veuillez remplir votre date de naissance"], }, education:[{ diplome:{type:String,required:[true,"Le champ est obligatoire"]}, etablissement:{type:String,required:[true,"Le champ est obligatoire"]}, annee_etude:{type:Number,required:[true,"Le champ est obligatoire"], enum:values[1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915, 1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932, 1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949, 1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966, 1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983, 1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000, 2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017, 2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030] } }], Skills:{type:[String],required:[true, "Champ obligatoire"],minlength:1}, langues:[{ langue: { type : String , required : true , enum:{values:["français","anglais","allemand","italien","espagnol","russe","turc","portugais"]} } , niveaux : {type : String ,enum : ["A1","A2","B1","B2","C1","C2"]} }], realisation:[{ date_realisation:{type:Date}, description:{type:String,maxLength: 2000}, intitule_projet: {type: String, maxLength: 100}, }], telephone:{type:String, validate:function(v){if(!(validator.isMobilePhone(v)))throw new Error("Numéro de téléphone invalide")}, required:[true,"Veuillez saisir votre numéro de téléphone"], unique:true}, photo_de_profil:{type:String}, cv:{type:String} }) export default mongoose.model('Employee',employeeSchema)
Employee Controller
import Employee from "../modules/employee" import multer from "multer" let cvfile="" let photofile = "" const photo_storage = multer.diskStorage({ destination:`${__dirname}/photoEmployee`, filename:(req,file,redirect)=>{ let date = Date.now() let fl = date + '.'+file.mimetype.split('/')[1] redirect(null,fl) photofile = fl } }) const photoUpload = multer({storage:photo_storage}).single('photo') const cv_storage = multer.diskStorage({ destination:`${__dirname}/CVEmployee`, filename:(req,file,redirect)=>{ let date = Date.now() let emp = new Employee() let fl = date+'.CV_'+emp.prenom+'_'+emp.nom+file.mimetype.split('/').pop() redirect(null,fl) cvfile = fl } }) const cvUpload = multer({storage:cv_storage}).single('cv') export const create = (async(req,res)=>{ try{ await photoUpload(req, res) await cvUpload(req, res) if (req.fileValidationError) { return res.status(400).json({ message: req.fileValidationError }); } const Employeedata = new Employee({ ...req.body, // Données de l'employé depuis la requête photo: photofile, // Ajouter le nom de fichier de la photo cv: cvfile, // Ajouter le nom de fichier du CV }); const {email} = Employeedata const EmployeeExist = await Employee.findOne({email}) if(EmployeeExist){ return res.status(400).json({message:"Employé est déja existe"}) } const savedEmployee = await Employeedata.save() res.status(200).json(savedEmployee) } catch(err){ res.status(500).json({message:"Internal server error"}) } finally{ cvfile = "" photofile = "" } })
Employee Router
import express from "express" import { create } from "../controllers/employeeController" const router = express.Router() router.post('/create_employee',create) export default router
关键修复步骤
在index.js中导入员工路由并挂载到主应用,示例代码:
// 导入员工路由(根据实际文件路径调整) import employeeRouter from './routes/employeeRouter.js'; // 挂载路由到主应用 app.use('/', employeeRouter);
内容的提问来源于stack exchange,提问作者Firas Abbessi
相关产品推荐
相关产品推荐

