尝试将表单数据发送到 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);
});
我知道类似的问题已经被问过很多次了,例如
但是,我尝试应用这些答案中的各种解决方案,但均未成功。
这是我的客户端页面:
<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);
});