Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is an object in an XMLHttpRequest sent to a Node/Express server empty?

I am trying to make a form that takes the email address and sends a transactional email back. I am using a XMLHttpRequest in vanilla JavaScript to send data to the server, but when I look at the data sent from index.html, it is only an empty object on the server side.

On the backend I am using Node and Express and Nodemailer. Nodemailer is working properly. I have been trying to figure out why the query object does not have anything in it.

// 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>
like image 324
jayscript Avatar asked Dec 19 '22 00:12

jayscript


1 Answers

A few things before this can work

  • Decide whether you want to use GET or POST, you seem to be confused as to which one to use. I would use POST because you're trying to send data for an email and not really trying to get data from the server.
  • Change your app.post node function (assuming you want post)
  • You need to send a string to the server, hence the json stringify
  • Since your string is in json format you need to change the header "Content-Type" to "application/json"
  • You need to change your request verb to 'POST' to match your server and what you are trying to accomplish

In your server you need to replace the app.post code with (you'll need to 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
  }
});

This should do the trick on the client

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));

Alternative Solution to XMLHttpRequest

Alternatively, you can look at this library for sugar over the HTTP api - axios

If you're using axios, it's as simple as

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

or if you want to control what happens when you receive a response.

data = {to: to, subject: subject, text: text};
axios.post('/user', data)
  .then(function (response) {
    console.log('success');
  })
  .catch(function (response) {
    console.log('error');
  });
like image 79
yangli-io Avatar answered Dec 24 '22 01:12

yangli-io