为什么通过XMLHttpRequest发送给Node/Express服务器的对象为空?

4
我正在尝试制作一个表单,它可以获取电子邮件地址并发送一封交易性电子邮件。我使用了纯JavaScript中的XMLHttpRequest将数据发送到服务器,但是当我查看从index.html发送的数据时,在服务器端只有一个空对象。
在后端,我使用Node、Express和Nodemailer。Nodemailer正常工作。我一直在努力弄清楚为什么查询对象里面没有任何内容。

// Here is server.js

var express = require('express');
var nodemailer = require('nodemailer');
var app = express();

// Send index.html
app.get('/', function(request, response) {
  response.sendfile('index.html');
});

// Where I should receive data from JS written in index.html
app.post('/send', function(req, res) {
  var mailOptions  =   {
    to: req.query.to,
    subject: req.query.subject,
    text: req.query.text
  }
});
<!-- Here is my index.html with some JS in it -->

<div>
  <input id="to" type="text" placeholder="Email" />
  <input id="subject" type="text" placeholder="subject" />
  <textarea id="content" cols="20" rows="2" placeholder="Write something"></textarea>
  <button id="submit">Submit</button>
</div>

<script>
  // When #submit is clicked it invokes a function to collect values and then makes a XMLHttpRequest like bellow
  data = {to: to, subject: subject, text: text};
  var request = new XMLHttpRequest();
  request.open('GET', 'http://localhost:3000/send', true);
  request.send(data);
  }
</script>


您的XMLHttpRequest发送了一个“GET”请求,但您的Express服务器期望收到一个“POST”请求。 - yangli-io
@PHPglue他放上来的代码片段是他实际代码的一部分,因此它是未定义的。 - yangli-io
1
使用 GET 方法时,.send() 不会发送任何内容,只会使用 .open() 中的 URL。如果您想要发送数据,请使用 POST 方法或将数据附加到 URL 上,例如:?to=val1&subject=val2&text=val3。或者您可以使用 jQuery,然后只需传递该数据对象即可。 - StackSlave
非常抱歉犯了这个错误。我不小心使用了.post而不是.get,因为我在不同的情况下尝试了这两个方法对。 - jayscript
1个回答

10

在进行这项工作之前需要注意以下几点:

  • 决定使用GET或POST方法,因为你好像对该如何选择有些困惑。我建议使用POST方法,因为你正试图发送一份邮件数据而不是获取服务器上的数据。
  • 更改app.post node函数(假设你要用post方法)
  • 你需要向服务器发送一个字符串,所以要使用JSON.stringify方法将其转换成字符串。
  • 由于你的字符串是以JSON格式编写的,因此你需要将请求头中的"Content-Type"更改为"application/json"。
  • 你需要将请求动词更改为'POST'以与服务器匹配并实现你的目标。

在服务器端,你需要用以下代码替换app.post代码(你需要先使用npm install body-parser安装相关模块):

var bodyParser = require('body-parser');
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
// Where I should receive data from JS written in index.html
app.post('/send', function(req, res) {
  var mailOptions  =   {
    to: req.body.to,
    subject: req.body.subject,
    text: req.body.text
  }
});

这应该能在客户端上起作用。

data = {to: to, subject: subject, text: text};
var request = new XMLHttpRequest();
request.open('POST', 'http://localhost:3000/send', true);
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(JSON.stringify(data));

XMLHttpRequest的替代方案

另一种选择是使用这个库来简化HTTP API - axios

如果你正在使用axios,那么只需要:

data = {to: to, subject: subject, text: text};
axios.post('/user', data);

或者,如果你想掌控当你收到响应时发生的事情。

data = {to: to, subject: subject, text: text};
axios.post('/user', data)
  .then(function (response) {
    console.log('success');
  })
  .catch(function (response) {
    console.log('error');
  });

我刚刚实现了更改,效果非常好。我也感谢提供的另一种解决方案,我会尝试一下。这真的是完美的答案! - jayscript
没关系 @jayscript,你能否勾选解决方案并点赞它呢? - yangli-io
这是我在 Stack Overflow 上的第一个问题。一旦我积累到 15 点声望,我会给你的答案点赞!我只需要再 5 点声望... - jayscript
“ticking the solution” 是什么意思?有没有办法显示我找到了解决方案? - jayscript
1
@YangLi - 这是一个很棒的答案。谢谢分享! - Farid
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接