Express+Handlebars表单提交404及属性访问权限报错求助
问题解决:POST请求404与Handlebars警告
控制台错误信息
GET /admin/add-product 200 70.156 ms - 3932 Handlebars: 解析属性"status"被拒绝,因为它不是父级的"自有属性"。 你可以添加运行时选项来禁用检查或此警告,详情可查看Handlebars官方文档的运行时选项章节。 POST /admin/add-product 404 31.120 ms - 3921
问题描述
我在Admin页面提交表单收集数据时,POST请求返回404"not found",控制台输出上述错误,但nodemon还在正常运行。相关代码文件如下:
相关代码文件
app.js
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); const { engine : hbs } = require("express-handlebars") var fileUpload = require('express-fileupload') var userRouter = require('./routes/user'); var adminRouter = require('./routes/admin'); var handlebars = require('handlebars') const template = handlebars.compile("{{aString.trim}}"); const result = template( { aString: " abc " }, { allowedProtoMethods: { trim: true } } ); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); app.engine('hbs',hbs({extname:'hbs',defaultLayout:'layout',layoutsDir:__dirname+'/views/layout/',partialsDir:__dirname+'/views/partials/'})) app.use(fileUpload()) app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', userRouter); app.use('/admin', adminRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
admin.js
var express = require('express'); const { log } = require('handlebars'); var router = express.Router(); /* GET users listing. */ router.get('/', function(req, res, next) { let products = [ { name:"Apple iPhone 15", description:"Apple iPhone 15 (128 GB) - Black", category:"Mobile", price:"₹72,690", image:"https://m.media-amazon.com/images/I/71657TiFeHL._SX679_.jpg" }, { name:"Apple iPhone 15 Plus", description:"Apple iPhone 15 Plus (128 GB) - Blue", category:"Mobile", price:"₹80,990", image:"https://m.media-amazon.com/images/I/71PjpS59XLL._SX679_.jpg" }, { name:"Apple iPhone 15 Pro", description:"Apple iPhone 15 Pro (1 TB) - Black Titanium", category:"Mobile", price:"₹1,77,990", image:"https://m.media-amazon.com/images/I/81+GIkwqLIL._SX679_.jpg" }, { name:"Apple iPhone 15 Pro Max", description:"Apple iPhone 15 Pro Max (256 GB) - Black Titanium", category:"Mobile", price:"₹1,48,900", image:"https://m.media-amazon.com/images/I/81Os1SDWpcL._SX679_.jpg" } ] res.render('admin/view-products',{products,admin:true}) }); router.get('/add-product',(req,res)=>{ res.render('admin/add-product') }) router.post('/admin/add-product',(req,res)=>{ console.log(req.body); console.log(req.files.Image); }) module.exports = router;
add-product.hbs
<section> <div class="container"> <div class="row"> <div class="col-md-6"> <h2 class="text-center">Add Product</h2> <form action="/admin/add-product" method="post" enctype="multipart/form-data"> <label for="">Name</label> <input type="text" name="Name" class="form-control"> <label for="">Description</label> <input type="text" name="Description" class="form-control"> <label for="">Category</label> <input type="text" name="Category" class="form-control"> <label for="">Price</label> <input type="text" name="Price" class="form-control"> <label for="">Image</label> <input type="file" name="Image" class="form-control"> <br> <button type="submit" class="btn btn-success">Submit</button> </form> </div> </div> </div> </section>
解决方案
1. 修复POST请求404问题
问题出在admin.js的POST路由配置:当前代码中路由是router.post('/admin/add-product', ...),但adminRouter已经通过app.use('/admin', adminRouter)挂载到/admin路径下,这会导致实际匹配的路径变成/admin/admin/add-product,和表单的action="/admin/add-product"不匹配。
修改admin.js中的POST路由:
router.post('/add-product',(req,res)=>{ console.log(req.body); console.log(req.files.Image); // 添加响应逻辑,比如重定向回添加页面 res.redirect('/admin/add-product'); })
2. 解决Handlebars警告问题
要消除"解析属性'status'被拒绝"的警告,需要在express-handlebars的引擎配置中添加运行时选项,允许访问原型属性或方法:
修改app.js中的引擎配置:
app.engine('hbs',hbs({ extname:'hbs', defaultLayout:'layout', layoutsDir:__dirname+'/views/layout/', partialsDir:__dirname+'/views/partials/', runtimeOptions: { allowProtoPropertiesByDefault: true, allowProtoMethodsByDefault: true } }))
内容的提问来源于stack exchange,提问作者Thejas Krishna L
相关产品推荐
相关产品推荐

