You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js Express 注册表单提交触发页面无限加载问题

问题根因
  • 核心触发点:POST路由注册时机错误。你将/create-new-acc的POST处理逻辑写在了http.listen()的回调函数内部,该回调仅在服务完成端口监听启动后异步执行1次,服务启动接收请求的时间早于路由注册时间,首批到达的请求无法匹配到处理逻辑;同时这种写法本身违背Express中间件/路由的注册规则,会导致路由匹配异常。
  • 直接导致挂起的原因:请求解析中间件重复且冲突。你先后注册了3次urlencoded请求解析(2次来自独立的body-parser包、1次为Express内置能力)、1次JSON解析,还额外全局挂载了express-formidable中间件。普通application/x-www-form-urlencoded格式的表单提交不需要formidable处理,多个解析中间件同时运行会争抢消费请求流,前一个中间件消费完流数据后,后续中间件会一直等待流数据传输完成,导致请求全程挂起,不会返回任何响应,浏览器就会一直处于等待状态,表现为无限加载。
  • 业务逻辑隐患:表单内所有输入控件都未配置name属性,就算请求链路正常,后端也无法通过req.body获取到用户提交的表单字段值。
修复方案
  • 调整路由注册位置:所有路由、中间件必须在调用http.listen()启动服务前完成注册,不要在listen的回调函数内编写路由、挂载中间件。
  • 清理冗余冲突中间件:高版本Express已经内置了body-parser的解析能力,不需要额外引入body-parser包;普通表单提交场景不需要使用formidable,删除重复、无用的解析中间件,只保留必要的解析逻辑即可。
  • 补全表单属性:给所有需要提交到后端的input控件添加对应name属性,属性值和后端要读取的字段名保持一致。

修复后参考代码

后端服务代码

const express = require('express');
const mysql = require('mysql');
const app = express();
const http = require('http').createServer(app);

// 仅保留必要的中间件,删除重复冗余项
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(express.static(__dirname + '/views'));
app.use("/public", express.static(__dirname + '/public'));

app.set('view engine', 'ejs');

const pool = mysql.createPool({
  connectionLimit : 10,
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'alazanidb'
});

// 服务启动前注册路由
app.post('/create-new-acc', (req,res) =>{  
  // 后续可在此处通过req.body读取表单字段、执行数据库入库逻辑
  res.redirect('/entry/signin');
})

// 所有逻辑注册完成后再启动监听
http.listen(3000, function(){
  console.log('服务运行在3000端口');
})

表单部分代码

<div class="registration-popup" id="regpopup">
  <form action="/create-new-acc" method="POST" >
    <div class="content">   
      <h1 id="h1">Create new account</h1>
      <div class="input">
        <input type="text" placeholder="First Name" class="inp"  id="name" name="firstName"/>
      </div>
      <div class="input">
        <input type="text" placeholder="Second Name" class="inp" id="secname" name="secondName"/>
      </div>
      <div class="input">
        <input type="text" placeholder="Username" class="inp" id="username" name="username"/>
      </div>
      <div class="input">
          <input type="tel" placeholder="Phone Number" class="inp" id="phone" name="phone"/>
      </div>
      <div class="input">
          <input type="text" placeholder="Address" class="inp" id="addres" name="address"/>
      </div>
      <div class="input">
        <input type="password" placeholder="Password" class="inp" id="pass" name="password"/>
      </div>
      <div class="input">
        <input type="password" placeholder="Repeat password" class="inp" id="repass" name="repeatPassword"/>
      </div>
      <input type="submit" id="register" value="register"  >
      <input type="button" id="reset" value="Reset" onclick="resett()" >
    </div>
  </form>
</div>

内容的提问来源于stack exchange,提问作者striker vinchester

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:51:27