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

通过Ajax XMLHttpRequest发送FormData时如何避免TypeError报错

问题根因

核心问题是函数名和内部赋值的全局变量重名,导致函数被覆盖:

  • 你声明了全局函数insertUser,但在函数内部执行insertUser = document.getElementById("insert_user")时,该变量没有加let/const声明,默认挂载到全局作用域
  • 第一次调用insertUser函数后,全局下的insertUser就从函数被覆盖成了id为insert_user的表单DOM对象,第二次点击按钮调用insertUser()时,自然会抛出「不是函数」的类型错误

额外注意:你代码里所有的xhttp、formData变量都没有声明,全部是隐式全局变量,也容易引发其他变量污染问题。

修正方案

只需要把insertUser函数内部的变量改名,同时给所有变量加上声明即可,修改后的JS代码如下:

function loadUsers() { 
  // 给xhttp加const声明,避免全局污染
  const xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("users_row").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "views/users_view.php", true);
  xhttp.send();
}

function insertUser() {
  const xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("saved_user").innerHTML = "<b class='text-primary'>用户已添加<b>"; 
      loadUsers();
      setTimeout(function() {
        document.getElementById("saved_user").innerHTML = "";
      }, 3000);
    }
  };
  xhttp.open("POST", "controller/insert_user.php", true);
  // 变量名改成和函数名不冲突的名字,加const声明
  const userForm = document.getElementById("insert_user");
  const formData = new FormData(userForm);
  xhttp.send(formData);
}

可选优化建议

如果要进一步规避这类作用域问题,可以放弃内联onclick绑定,改用JS事件绑定:

  1. 删除HTML按钮上的onclick="insertUser()"属性
  2. 在JS代码末尾新增如下绑定逻辑:
document.querySelector('#insert_user button[type="button"]').addEventListener('click', insertUser);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 17:06:03