Node.js 表单数据通过XMLHttpRequest发布两次,一次作为空对象,一次使用正确的数据

Node.js 表单数据通过XMLHttpRequest发布两次,一次作为空对象,一次使用正确的数据,node.js,ajax,express,xmlhttprequest,Node.js,Ajax,Express,Xmlhttprequest,我正在学习web开发,其中包括AJAX。对于这个特定的示例,我在浏览器和节点上使用XMLHttpRequest对象,并使用Express作为我的服务器。 我有一个简单的HTML表单,需要将数据发布到节点服务器。我知道数据已成功发布,因为我可以在chrome的“网络”选项卡中看到表单数据 我的代码有几个问题,在过去的三天里,我一直在寻找Stackoverflow的答案,还查看了MDN文档,但我无法理解这一点 以下问题与张贴的代码有关: 如果submitForm()返回true,则我会将数据发布两次

我正在学习web开发,其中包括AJAX。对于这个特定的示例,我在浏览器和节点上使用XMLHttpRequest对象,并使用Express作为我的服务器。 我有一个简单的HTML表单,需要将数据发布到节点服务器。我知道数据已成功发布,因为我可以在chrome的“网络”选项卡中看到表单数据

我的代码有几个问题,在过去的三天里,我一直在寻找Stackoverflow的答案,还查看了MDN文档,但我无法理解这一点

以下问题与张贴的代码有关:

  • 如果submitForm()返回true,则我会将数据发布两次到服务器,一次为空请求正文,一次为预期数据。为什么?
  • 如果submitForm()返回false,则不会向服务器发回任何数据。为什么?
  • 如果根本没有对submitForm()的调用(即,没有对XHR的调用),那么表单数据将正确发布,这可以在服务器端的req.body中看到。
  • 如果我将xhr上的RequestHeader设置为application/x-www-form-urlencoded,则得到的结果就是
  • 如何使用XMLHTTPRequest获取表单以将数据发布到服务器
  • 我完全迷路了,不知道我错过了什么。如果有人能给我点灯,我将不胜感激

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
    
    <script>
    "use strict";
    function submitForm()
    {
      var formElement = document.getElementById("myForm");
      var formData = new FormData(formElement);
    
      var xhr = new XMLHttpRequest();
      xhr.open("POST", "/Test", true);
      xhr.send(formData);
      //return false;
    }
    </script>
    </head>
    
    <body>
    <form id="myForm" method="POST" action="/Test" onsubmit="return submitForm();" >
       <input type="text" value="John" name="name"/>
       <input type="submit" value="Send Data"/>
    </form>
    </body>
    </html>
    

    在浏览了你的代码并亲自测试之后。我发现

  • 为了回答第一个问题,您实际上提交了两次数据“John”。第一次是通过“submitForm()”函数。第二次是通过元素属性方法=“POST”,action=“/Test”

  • submitForm函数实际上正在工作,但您正在使用XMLHttpRequest()将post请求发送到服务器。如果阅读文档,XMLHttpRequest将使用多部分/表单数据enctype发送表单数据。因此,您的路由必须能够处理多部分/表单数据格式

  • 要确定是否确实调用了submitForm()函数,您可以始终在函数中添加一个警报(')。如果调用了该警报,将弹出一个提示。这始终是一个很好的调试方法

  • XMLHttpRequest()发送的格式:多部分/表单数据,处理的格式:URLCoded,这里有点不匹配

  • 最后,让我们讨论解决方案。正如我所说,您的路由需要能够处理多部分/表单数据

  • var express=require('express');//我不知道为什么不能将此行格式化为代码:/

    var bodyparser = require('body-parser');
    var multer = require('multer') // Use this module to add a middleware onto your route
    var mult_handler = multer() // creates a handler object
    
    var app = express();
    app.use(express.static('./'));
    
    var urlencoded = bodyparser.urlencoded({extended:true});
    
    app.get('/Test', function(req, res){
        res.sendFile(__dirname+'/Test.html');
    });
    
    app.post('/Test', mult_handler.none(), function(req, res){ 
        console.log("In POST");
        console.log(req.body);
        res.sendFile(__dirname+'/Test.html');
    });
    
    app.listen(8080);
    console.log('Now listening on port 8080...');
    

    非常感谢您花时间回答@CodeCodey。处理内容类型的路由确实解决了我的问题。我尝试了您的解决方案;它成功了,只是我必须使用mult_handler.none()使其工作。只是mult_handler错误:“route.post()需要回调函数,但得到了一个[object object]”。那么,发布HTML表单的普遍做法是什么呢?您是应该在表单提交时始终返回false,还是应该取消表单上的POST和action属性,还是应该完全忽略XHR路由,因为按钮无论如何都会发布表单?我太笨了,没有复制none()哈哈,无论如何,我们需要对对象错误进行进一步的调试,以前遇到过一次,但我有点忘记了如何解决它。对我来说,我只使用表单元素,就像它使用action和method的属性将数据发送回服务器一样。然后我的路由将接受application/json,因为它的处理和读取非常简单。这是我的首选,保持简单,以便每个人都能理解。更新“Route.post()需要回调函数,但出现[object object]”错误,请删除“//replace your url…mult handler”上的注释,因为我也遇到了这个问题。我认为编辑器(repl.it)无法容纳整个注释,因此编译器将其视为代码。删除它,您就可以开始了。另外,我已经更新了答案,以显示这一点。因此,如果您使用表单的方法和动作属性,您会使用body parser还是multer?我问,因为body parser将能够读取application/json。是的,我将使用body parser json
    var bodyparser = require('body-parser');
    var multer = require('multer') // Use this module to add a middleware onto your route
    var mult_handler = multer() // creates a handler object
    
    var app = express();
    app.use(express.static('./'));
    
    var urlencoded = bodyparser.urlencoded({extended:true});
    
    app.get('/Test', function(req, res){
        res.sendFile(__dirname+'/Test.html');
    });
    
    app.post('/Test', mult_handler.none(), function(req, res){ 
        console.log("In POST");
        console.log(req.body);
        res.sendFile(__dirname+'/Test.html');
    });
    
    app.listen(8080);
    console.log('Now listening on port 8080...');