为何Express的req.body无法获取指定表单的字段值?
问题描述
使用Express框架开发时,其他路由中req.body均可正常获取表单数据,但在POST /authoritysubmissioncopy/:copyrights_id路由中,获取表单内name为acceptoffers的单选框值与name为ffff的备注输入框值时,控制台显示这两个值均为undefined。已配置body-parser中间件,表单设置了enctype="multipart/form-data"。
HTML表单代码
<form action="/authoritysubmissioncopy/<%= copyrights[0].copyrights_id%>" method="post" enctype="multipart/form-data"> <table id="table-mix"> <tr> <td>Faculty ID*</td> <td><input class="form-control" placeholder="Faculty ID" name="Facultyid" value="<%= copyrights[0].facultyid %>" disabled> </td> </tr> <tr> <td>Faculty Name*</td> <td><input class="form-control" placeholder="Faculty Name" name="Facultyname" value="<%= copyrights[0].facultyname %>" disabled></td> </tr> <tr> <td> Title*</td> <td><input type="text" class="form-control" value="<%= copyrights[0].Title %>" placeholder="Title" name="title" disabled></td> </tr> <tr> <td>URL(if any)</td> <td><input type="url" value="<%= copyrights[0].Url %>" class="form-control" placeholder="Url" name="url" disabled></td> </tr> <tr> <td> date</td> <td><input type="text" value="<%= copyrights[0].date %>" required class="form-control" placeholder="date" name="date" disabled></td> </tr> <tr> <td>Status*</td> <td><input type="text" value="<%= copyrights[0].status %>" required class="form-control" placeholder="date" name="date" disabled> </td> </tr> <tr> <td> <label for="Online">Upload proof</label></td> <td><a href="/imageviewcopy/<%= copyrights[0].copyrights_id %>">View Proof</a> <label style="color: brown;" disabled>( <%= copyrights[0].path %>)</label></td> </tr> </table> <br> <div class="container"> <div class="button-wrap"> <input class="hidden radio-label" type="radio" name="acceptoffers" value="Approved" id="yes-button" /> <label class="button-label" for="yes-button"> <h1>Approved</h1> </label> <input class="hidden radio-label" type="radio" name="acceptoffers" value="Rejected" id="no-button"/> <label class="button-label" for="no-button"> <h1>Rejected</h1> </label> <input class="hidden radio-label" type="radio" name="acceptoffers" value="Hold" id="maybe-button"/> <label class="button-label" for="maybe-button"> <h1>Hold</h1> </label> </div> </div> <input type="text" class="input100" value="<%= copyrights[0].remark %>" placeholder=" Remark" name="ffff"> <button class="button" style="vertical-align:middle" align="center"><span>Submit </span></button> </div> </form>
app.js相关代码
var createError = require('http-errors'); var connection = require('./server'); var express = require('express'); var app = express(); var bodyparser = require('body-parser'); const jwt = require('jsonwebtoken') var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var flash = require('connect-flash'); var session = require('express-session'); const secretkey="secretkeysvpcet"; //const auth = require("./middleware/auth"); app.use(express.urlencoded({ extended:false })); const upload = require("./uploader"); const{check} = require('express-validator'); var dateTime = require('node-datetime'); const { json } = require('body-parser'); var dt = dateTime.create(); var formatted = dt.format('Y-m-d H:M:S'); var defaultaction="In process"; app.use(express.static(path.join(__dirname, '/public'))); app.use(bodyparser.json()); app.use(bodyparser.urlencoded({extended:false})); app.use(session({ secret :secretkey, resave:true, saveUninitialized:true })); app.use(cookieParser()); app.use(flash()); //View tables app.set('view engine','ejs'); app.set('views', path.join(__dirname, 'views')); .... app.post('/authoritysubmissioncopy/:copyrights_id',function(req, res) { connection.connect(function(error){ if(error) console.log(error); var copyrights_id = req.params.copyrights_id; var action =req.body.acceptoffers; var Remark =req.body.ffff; console.log(action,Remark); connection.connect(function(err) { if (err) throw err; var sql ="Update copyrights SET action='"+action+"',remark='"+Remark+"' where copyrights_id='"+copyrights_id+"'"; var sql2="Insert into log_data (activity,dateandtime) VALUES ('"+" Copyrights Id "+" "+copyrights_id+" "+" was "+""+action+" "+" By Authority "+"','"+formatted+"')"; connection.query(sql,function(err, result){ if (err) { throw err; } else{ connection.query(sql2,function(err,result){ if (err) {throw err;} else{ req.flash('message','Changes done Successfully'); res.redirect('/adminpage'); } }); } }); }) ; }); });
问题原因与解决方法
核心原因
body-parser中间件不支持解析multipart/form-data类型的表单数据,这是导致req.body无法获取字段值的根本原因。其他路由能正常获取数据,是因为那些表单未设置enctype="multipart/form-data",默认的application/x-www-form-urlencoded编码可被body-parser处理。
解决步骤
1. 移除不必要的enctype(无文件上传需求时)
如果表单不需要上传文件,直接删除enctype="multipart/form-data"属性,表单默认使用application/x-www-form-urlencoded编码,body-parser即可正常解析req.body:
<form action="/authoritysubmissioncopy/<%= copyrights[0].copyrights_id%>" method="post">
2. 使用multer处理文件上传(需文件上传时)
若表单需要上传文件,必须用multer中间件解析multipart/form-data数据:
步骤1:安装multer
npm install multer
步骤2:配置multer并应用到路由
在app.js中引入并配置:
const multer = require('multer'); // 仅解析普通字段,不保存文件 const upload = multer();
修改目标路由,添加upload.none()中间件:
app.post('/authoritysubmissioncopy/:copyrights_id', upload.none(), function(req, res) { connection.connect(function(error){ if(error) console.log(error); var copyrights_id = req.params.copyrights_id; var action = req.body.acceptoffers; var Remark = req.body.ffff; console.log(action, Remark); // 后续数据库操作代码... }); });
3. 额外优化建议
- 给单选框设置默认选中项:避免用户未选择时
req.body.acceptoffers为undefined,例如:
<input class="hidden radio-label" type="radio" name="acceptoffers" value="Approved" id="yes-button" checked />
- 修复SQL注入漏洞:不要直接拼接SQL语句,改用参数化查询:
var sql = "Update copyrights SET action=?, remark=? where copyrights_id=?"; connection.query(sql, [action, Remark, copyrights_id], function(err, result) { if (err) throw err; // 后续操作 });
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

