Node.js Express框架客户端POST请求重复发送两次如何解决
POST请求重复提交问题排查与修复

核心触发原因
- 事件重复绑定:页面局部刷新、评论区重新渲染等逻辑会导致提交按钮的点击事件被多次绑定,单次点击会触发多次AJAX调用。
- 服务端异步逻辑异常:原服务端代码中
User.findOne为异步操作,未等待查询完成就直接使用查询结果user,会抛出未定义异常,缺少异常捕获逻辑导致请求无响应,浏览器超时后会自动重试POST请求。 - 未设置提交状态锁:网络延迟情况下用户多次点击也会触发重复提交。
修复后的代码
客户端代码
// 绑定前先解绑原有事件,避免重复绑定 $('.commentSubmit').off('click').click(e => { e.preventDefault() // 状态锁,防止重复提交 if ($(this).attr('data-submitting') === '1') return $(this).attr('data-submitting', '1') let commentContent = $('#Comment').val() let postId = $('#input-comment').val() $.ajax({ url: '/dashboard/postComment', type: 'POST', data: { postId: postId, comment: commentContent } }) .done(data => { let htmlcomment = ` <li class="list-group-item mt-3" id="${data._id}"> <h6 class="card-title" >${data.Owner} <p class="card-text"><small class="text-muted">${data.createAt} </small></p> </h6> <h6 class="card-subtitle mb-2 text-muted"></h6> <p class="card-text" >${data.content} </p> <div class="card-footer text-muted" style="text-align: right;"> <button type="button" id="commentdelete" data-id="${data._id}" class="btn btn-danger btn-sm commentdelete">Delete</button> </div> </li>` $(`ul#${postId}ulul`).prepend(htmlcomment) document.getElementById('Comment').value = '' }) .always(() => { // 请求完成后重置状态锁 $(this).attr('data-submitting', '0') }) })
服务端代码
router.post('/postComment', async (req, res) => { console.log('done') req.connection.setTimeout( 1000 * 60 * 10 ) try { if(!req.session._id) { return res.redirect('/login') } if(!req.body.comment || !req.body.postId) { return res.render('dashboard',{errors: 'Input comment first', user: u, posts: post, comments: comment, notifs: notif}) } const postId = req.body.postId // 等待用户查询完成再执行后续逻辑 const user = await User.findOne({_id: req.session._id}) console.log(req.url) const post = await Posts.findOne({_id: postId}) if(!post) { return res.send('PostID NOT Valid') } const comment = new Comments({ content: req.body.comment, Owner: user.name, PostId: postId }) await comment.save(); return res.json(comment) } catch (err) { // 捕获所有异常返回响应,避免请求挂起 console.error(err) return res.status(500).send('服务器处理错误') } })
内容的提问来源于stack exchange,提问作者Flason
相关产品推荐
相关产品推荐

