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

无法通过XMLHttpRequest从客户端向Node.js服务器发送JSON字符串(POST请求)求助

解决前端发送JSON到Node.js服务器后req.body为空的问题

我刚仔细扒了你的代码,发现几个关键坑导致服务器拿不到数据,咱们一步步捋清楚:

前端代码的核心错误

这些问题直接导致你的JSON请求要么没发出去,要么发的是无效数据:

  • 没阻止表单默认提交行为:按钮在<form>标签里,点击后会触发表单自带的POST跳转,直接打断你的XHR请求——页面都跳走了,请求自然没发完。
  • 获取输入值方式错了:document.querySelector("#name")拿到的是DOM元素本身,不是用户输入的内容,得用.value属性取实际值。
  • 请求URL缺协议:localhost:4000会被浏览器当成相对路径,得写成http://localhost:4000才能正确指向服务器。
  • result变量未定义:你直接用result.innerHTML,但没提前获取这个DOM元素。
  • 多余的alert阻塞请求:alert(xhr)会卡住代码执行,完全没必要留着。

修改后的前端代码:

<!DOCTYPE html> 
<html> 
<head> 
<title> JavaScript | Sending JSON data to server. </title> 
</head> 
<body style="text-align:center;" id="body"> 
<h1 style="color:green;"> Post Product </h1> 
<form action='/' method="POST"> 
<input type="text" id="name" placeholder="Product Name"> 
<input type="text" id="price" placeholder="Price"> 
<button id="btn">Send JSON</button> 
<p class="result" style="color:rgb(6, 177, 6)"></p> 
</form> 
<script> 
let button = document.querySelector("#btn"); 
let result = document.querySelector(".result"); // 先拿到结果显示元素
button.addEventListener("click", sendJSON, true); 

function sendJSON(e) { 
  e.preventDefault(); // 关键!阻止表单默认跳转
  let nameInput = document.querySelector("#name"); 
  let priceInput = document.querySelector("#price"); 
  // 取输入框的实际值
  let name = nameInput.value;
  let price = Number(priceInput.value); // 价格转成数字类型更合理

  let url = "http://localhost:4000"; 
  let xhr = new XMLHttpRequest(); 

  xhr.onreadystatechange = function () { 
    if (xhr.readyState === 4) {
      if (xhr.status === 201) { 
        result.innerHTML = this.responseText; 
      } else {
        result.innerHTML = `请求失败:${xhr.status}`;
      }
    }
  }; 

  const json = [{name: name, price: price}]; 
  xhr.open('POST', url, true); 
  xhr.setRequestHeader('content-type', 'application/json'); 
  xhr.send(JSON.stringify(json)); 
} 
</script> 
</body> 
</html>

后端代码的优化点

你的后端其实大方向是对的,只是有两个细节补全就完美了:

  • 确保express.json()中间件在路由前加载:你现在的顺序是对的(先加载解析中间件,再定义路由),如果反过来会导致服务器无法解析JSON请求体,这点要记牢。
  • 给前端返回响应:之前后端只打印日志,不返回响应的话,前端XHR会一直处于等待状态,得加一句响应代码让前端知道请求成功了。

修改后的后端路由部分:

server.post('/', function(req,res) { 
  console.log('收到的请求体:', req.body); 
  // 返回响应给前端
  res.status(201).json({
    message: "数据接收成功",
    receivedData: req.body
  });
}); 

为什么之前req.body是空的?

核心原因是表单默认跳转打断了XHR请求,你的JSON根本没成功发送到服务器;退一步说,就算请求发出去了,你传的是DOM元素而非输入值,服务器解析后自然是空对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:57:50