为什么 req.body 是一个空对象?

Why is req.body an empty object?

我正在尝试学习 XMLHttpRequests。我正在尝试向服务器发送一些输入,但是当它到达那里时,对象是空的,例如 {} 那个 setRequestHeader 我注释掉了,如果它在里面,对象会被正确打印出来,但是我得到一个错误,它应该在浏览器上打开。但是如果我把它放在 open() 语句之后,它会再次停止工作并且对象变空了。我也尝试了所有这些以及 JSON.stringfy 发送变量之前的变量,但它也没有用。

//server.js
const express = require('express');
const app = express();
const cors =require('cors')

app.use(cors())

app.use(express.urlencoded({extended:true}))

app.post('/frases', function(req, res) {
    console.log(req.body);
    const frase = new phrase(req.body);
    // console.log(frase);
})

app.listen(3000, () => console.log('listening on 3000...'));

//script.js
var form = document.getElementsByTagName('form')[0];

const xhr = new XMLHttpRequest();
// xhr.setRequestHeader('Content-Type', 'application/json');

form.onsubmit = (e) => {
    e.preventDefault();
    const thisName = form.elements[0].name;
    const thisValue = form.elements[0].value;
   
    const frase = {[thisName]:thisValue};
    console.log(frase)
    xhr.open('POST', 'http://localhost:3000/frases');
    xhr.send(frase);

    }; 


<!-- index.html -->
    <form action = "http://localhost:3000/frases" method="post">
        <label for="frasefavorita"> Qual é a sua frase favorita?
            <input id= 'frase' type="text" name="frasefavorita">
            <button id= 'send-frase' type="submit">Enviar</button>
    </form>

调用open函数后尝试设置header

xhr.open('POST', 'http://localhost:3000/frases');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(frase);

req.body默认为空,因为默认不读取传入请求的body。您需要与传入的 content-type 匹配的中间件才能读取 body、解析它并将结果放入 req.body.

而且,在你的 xhr 调用中,你必须决定 content-type 你将使用什么来发送数据,必须将数据放入那个 content-type 并且你必须设置header 适当。然后,您将能够将正确的中间件添加到您的服务器以读取和解析 body,然后,只有这样,您才能在服务器上的 req.body 中访问它。

如果您打算将其作为 JSON 发送,那么您可以在客户端上执行此操作,为 JSON 设置 content-type 并将数据格式化为 [=43] =]:

form.onsubmit = (e) => {
    e.preventDefault();
    const thisName = form.elements[0].name;
    const thisValue = form.elements[0].value;
   
    const frase = {[thisName]:thisValue};
    const xhr = new XMLHttpRequest();
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.open('POST', 'http://localhost:3000/frases');
    xhr.send(JSON.stringify(frase));

}; 

然后,在您的服务器上,您可以在 /frases 路由处理程序之前添加此中间件:

// read and parse incoming JSON request bodies
app.use(express.json());

这将读取并解析来自您的 Ajax 调用的 application/json content-type 数据。

P.S。我建议您使用 fetch() 接口来编写新代码,而不是 XMLHttpRequest API。 fetch() 更易于使用且设计更现代(使用 promises)。