尝试将表单数据发送到 Express 应用程序,无法正确解析为 req.body

Trying to send form data to Express app, can't parse into req.body correctly

我知道类似的问题已经被问过很多次了,例如.

但是,我尝试应用这些答案中的各种解决方案,但均未成功。

这是我的客户端页面:

<form id="submit_newuser" method="POST" action="/submit_newuser">
    User name:
    <input type="text" id="username" name="username" />
    <br>
    Phone number:
    <input type="text" id="phonenumber" name="phonenumber" />
    <br><br>
    <input type="submit" />
</form>

<script>
document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);

function submit_newuser(event){
    event.preventDefault();
    submit_newuserForm=document.getElementById("submit_newuser");
    formData=new FormData(submit_newuserForm);
    fetch("/submit_newuser",{
        body:formData,
        headers:{
            "Content-Type": "application/json"
        },
        method:"post"
    })
    .then(response=>console.log(response))
    .catch(err=>"submit_newuser: error: "+err);
}
</script>

下面是 /submit_newuser 端点的相关服务器端代码:

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.post('/submit_newuser',function(req,res){
    console.log("/submit_newuser: req.body: "+JSON.stringify(req.body));
    var phonenumber=req.body.phonenumber;
    var username=req.body.username;
    var output="you submitted: "+username+" "+phonenumber;
    console.log("/submit_newuser: text to send back: "+output);
    res.send(output);
});

有了这个,当我从页面提交数据时,服务器记录了这个错误:

SyntaxError: Unexpected token - in JSON at position 0

当我将 Content-Type 更改为 "application/x-www-form-urlencoded" 时,我得到了这个控制台日志记录:

/submit_newuser: req.body: {"------WebKitFormBoundaryBDU4OcntAv7d5wWL\r\nContent-Disposition: form-data; name":"\"username\"\r\n\r\ntestUserName\r\n------WebKitFormBoundaryBDU4OcntAv7d5wWL\r\nContent-Disposition: form-data; name=\"phonenumber\"\r\n\r\ntestPhoneNumber\r\n------WebKitFormBoundaryBDU4OcntAv7d5wWL--\r\n"}

/submit_newuser: text to send back: you submitted: undefined undefined

这表示数据正在 posted 到服务器,但未正确解析为 req.body

涉及 multer 的解决方案似乎不适用于此处,因为我没有上传文件,但我不确定我是否应该使用与 posting 不同的方法fetch() 正文中的 FormData 对象。

我很困惑,也想知道是否有更简单的方法来做到这一点。我只想 post 在不触发页面刷新的情况下向服务器形成数据,并能够使用服务器响应更新页面元素。

使用下面的示例 ajax 调用从前端发送数据。

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "http://localhost:3000/submit_newuser",
  "method": "POST",
  "data": {
    "username": "test user",
    "phonenumber": "03453512545"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});

示例邮递员请求。

您可以像这样更新您的 client-side 代码以发送 JSON body,这将被服务器正确解析。

因为我们在客户端上将 content-type header 设置为 JSON,所以我们必须发送 JSON 数据。我们可以发送 url 编码数据或 multipart/form-data,但是我们必须在客户端上更改 headers 才能做到这一点。

document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);

function formDataToJson(formData) {
    const obj = {};
    formData.forEach((value, key) => { 
        obj[key] = value
    });
    return JSON.stringify(obj);
}

function submit_newuser(event){
    event.preventDefault();
    submit_newuserForm=document.getElementById("submit_newuser");
    formData = new FormData(submit_newuserForm);
    fetch("/submit_newuser",{
        body: formDataToJson(formData),
        headers: {
            "Content-Type": "application/json"
        },
        method:"post"
    })
    .then(response=>console.log(response))
    .catch(err=>"submit_newuser: error: "+err);
}

如果您尝试将客户端请求作为 formData 发送,那么您必须处理后端以将请求作为 formData 接收。

有一个名为 multer 的 npm 模块用于处理 formData 请求类型。

无论如何,您的代码必须更改为如下内容:

客户端

<script>

 document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);

  function submit_newuser(event){
    event.preventDefault();
    submit_newuserForm=document.getElementById("submit_newuser");
    formData=new FormData(submit_newuserForm);
    fetch("http://127.0.0.1:3000/submit_newuser",{
        body:formData,
        method:"post"
    })
    .then(response=>console.log(response))
    .catch(err=>"submit_newuser: error: "+err);
}
</script>

服务器端

const multer = require('multer');
const upload = multer();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.post('/submit_newuser', upload.none(), function (req, res) {
  console.log("/submit_newuser: req.body: " + JSON.stringify(req.body));
  var phonenumber = req.body.phonenumber;
  var username = req.body.username;
  var output = "you submitted: " + username + " " + phonenumber;
  console.log("/submit_newuser: text to send back: " + output);
  res.send(output);
});