Nim Prologue函数数据传递异常:后端接收前端提交数据为空
后端无法获取Fetch提交的表单参数问题
问题描述
我编写了HTML和JS前端代码,通过fetch接口/sona-master/availability-json提交表单数据,但基于Nim Prologue实现的后端checkRoom函数无法获取提交的参数,接收值为空。附上前后端代码及仓库地址,请求协助排查解决。
前端代码
<div class="col-lg-4"> <div class="room-booking"> <h3>Your Reservation</h3> <form id="f2" method="post" action="" class="needs-validation"> <input type="hidden" name="room_id" value="1"> <div class="check-date"> <label for="date-in">Check In:</label> <input type="text" class="date-input" name="start" id="date-in" autocomplete="off"> <i class="icon_calendar"></i> </div> <div class="check-date"> <label for="date-out">Check Out:</label> <input type="text" class="date-input" id="date-out" name="end" autocomplete="off"> <i class="icon_calendar"></i> </div> <div class="select-option"> <label for="guest">Guests:</label> <select id="guest"> <option value="">3 Adults</option> </select> </div> <div class="select-option"> <label for="room">Room:</label> <select id="room"> <option value="">1 Room</option> </select> </div> <button type="submit" id="b2">Check Availability</button> </form> </div> </div> </div> </div> </section> <!-- Room Details Section End --> <script> const dateIn = document.getElementById('date-in'); const dateOut = document.getElementById('date-out'); if (dateIn !== null && dateOut !== null) { document.getElementById('b2').onclick = function(event){ event.preventDefault(); console.log('clicked'); let form = document.getElementById('f2'); let formData = new FormData(form); formData.append("room_id", "1") fetch('/sona-master/availability-json', { method: 'post', body: formData, }) .then(response => response.json()) .then(data => { if (data.ok) { Notiflix.Notify.success('<p>Room is available</p>' + '<p><a href="#!" class="btn btn-primary">' + 'Book Now</a></p>') } else { Notiflix.Notify.failure('Room is not available') } }) }; } </script>
后端代码(Nim)
import prologue, json import times import asyncdispatch import strutils import ../views/[index, layout, choose_room] import ../database/roomrestrictions import ../models/models proc checkRoom*(ctx: Context) {.async.} = var sd = ctx.getFormParams("start") var ed = ctx.getPostParams("end") var startDate = parse(sd, "d MMMM, yyyy") var endDate = parse(ed, "d MMMM, yyyy") roomi = ctx.getPostParams("room_id") var roomID = parseInt(roomi) # roomID = parseInt(room_id) echo roomID var db = newDatabase3() available = db.searchAvailabilityByDatesByRoomID(startDate, endDate, roomID) a = %* {"ok": available, "message": "", "roomID": $roomID, "startDate": sd, "endDate": ed} resp jsonResponse(a)
仓库地址
GitLab仓库:https://gitlab.com/a60030/aa
排查与解决方案
核心问题分析
- Prologue未启用Multipart解析:前端用
FormData提交数据时,请求头Content-Type为multipart/form-data,而Prologue默认未开启该类型的解析支持,导致后端无法读取参数。 - 参数获取方法混用:后端同时使用
getFormParams和getPostParams,getFormParams通常用于解析URL查询参数,而非POST表单数据,应该统一使用getPostParams。 - 路由路径不匹配:前端请求路径是
/sona-master/availability-json,需确认后端路由是否绑定了该完整路径,若后端仅绑定/availability-json,则路径不匹配导致参数无法接收。 - 参数未做空值处理:直接对空字符串调用
parse会报错,需先判断参数是否为空。
具体修复步骤
1. 后端启用Multipart解析
在Prologue应用初始化时添加enableMultipart = true,确保能解析FormData:
let app = newApp(settings = newSettings(enableMultipart = true))
2. 统一使用getPostParams获取参数
修改后端checkRoom函数,全部用getPostParams获取POST参数,并添加空值判断:
proc checkRoom*(ctx: Context) {.async.} = var sd = ctx.getPostParams("start", default = "") var ed = ctx.getPostParams("end", default = "") var roomi = ctx.getPostParams("room_id", default = "") if sd.len == 0 or ed.len == 0 or roomi.len == 0: resp jsonResponse(%*{"ok": false, "message": "Missing required parameters"}) return let startDate = parse(sd, "d MMMM, yyyy") let endDate = parse(ed, "d MMMM, yyyy") let roomID = parseInt(roomi) echo roomID let db = newDatabase3() let available = db.searchAvailabilityByDatesByRoomID(startDate, endDate, roomID) let a = %* {"ok": available, "message": "", "roomID": $roomID, "startDate": sd, "endDate": ed} resp jsonResponse(a)
3. 确认路由路径匹配
检查后端路由注册代码,确保路径与前端请求一致:
app.post("/sona-master/availability-json", checkRoom)
如果后端没有/sona-master前缀,需修改前端fetch的URL为/availability-json。
4. 前端优化(可选)
给select标签添加name属性,确保这些参数能被FormData收集:
<select id="guest" name="guest"> <option value="">3 Adults</option> </select> <select id="room" name="room"> <option value="">1 Room</option> </select>
内容的提问来源于stack exchange,提问作者me0045
相关产品推荐
相关产品推荐

