Reputation: 1367
I am trying to send form data to the backend using fetch API but when I console.log my request.body
it returns an empty object {}
. What I was trying to send to my backend was the firstname, lastname, email, and message the user inputted. Why isn't the object containing the data. Where did I go wrong. Any help is appreciated. Thanks in advance.
//backend
const express = require('express');
const app = express();
app.listen(3000, () => console.log('listening at port 3000'));
app.use(express.static('public'));
app.use(express.json({
limit: '1mb'
}));
app.post('/api', (request, response) => {
console.log('I got a request') //Prints I got a request
console.log(request.body); //Prints {} (empty object)
});
//frontend
function proccessContactMessage() {
firstName = document.getElementById('contactUsFirstName').value
lastName = document.getElementById('contactUsLastName').value
email = document.getElementById('contactUsEmail').value
message = document.getElementById('contactUsMessage').value
const data = {
firstName,
lastName,
email,
message
};
const options = {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
fetch('http://localhost:3000/api', options);
}
<form class="formContactUs">
<div class="contactUsTitleCon">
<h2 class="contactUsTitle">Contact Us</h2>
</div>
<div class="form-group">
<label for="contactUsFirstName">First Name</label>
<input type="text" class="form-control" id="contactUsFirstName" placeholder="Enter First Name" required>
</div>
<div class="form-group">
<label for="contactUsLastName">Last Name</label>
<input type="text" class="form-control" id="contactUsLastName" placeholder="Enter Last Name" required>
</div>
<div class="form-group">
<label for="contactUsEmail">Email</label>
<input type="email" class="form-control" id="contactUsEmail" placeholder="Enter Email" required>
</div>
<div class="form-group">
<label for="contactUsMessage">Message</label>
<textarea class="form-control" id="contactUsMessage" placeholder="Enter Message" required></textarea>
</div>
<div class="contactUsSubmitBtnCon"><button type="submit" class="btn btn-primary contactUsSubmitBtn" onclick="proccessContactMessage()">Submit</button></div>
</form>
Upvotes: 1
Views: 2019
Reputation: 2906
I guess, you need a body parser ! You can use the body-parser
or the express.urlencoded()
.
Try this:
In your app.js:
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));// we need to register a parser, to parse the incoming request body !
Or, you can replace that with:
app.use(express.urlencoded({ extended: true })); //Parse URL-encoded bodies
Then, you can do:
console.log(req.body);
Upvotes: 0
Reputation: 2906
As I can understand from our exchange of comments in my first answer, the problem comes from the CORS. If so, try this:
const cors = require('cors');
const corsOptions = {
origin: (origin, callback) => {
callback(null, true);
},
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
allowedHeaders: ["Access-Control-Allow-Origin", "Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"],
credentials: true
};
app.options('*', cors(corsOptions));
app.use(cors(corsOptions));
Upvotes: 1
Reputation: 13050
In the function proccessContactMessage() you defined data as:
const data = {
firstName,
lastName,
email,
message
};
But this is not a valid JSON object.
//frontend
function proccessContactMessage() {
firstName = document.getElementById('contactUsFirstName').value
lastName = document.getElementById('contactUsLastName').value
email = document.getElementById('contactUsEmail').value
message = document.getElementById('contactUsMessage').value
const data = {
firstName: firstName,
lastName: lastName,
email: email,
message: message
};
console.log(data);
const options = {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
fetch('http://localhost:3000/api', options);
}
<form class="formContactUs">
<div class="contactUsTitleCon">
<h2 class="contactUsTitle">Contact Us</h2>
</div>
<div class="form-group">
<label for="contactUsFirstName">First Name</label>
<input type="text" class="form-control" id="contactUsFirstName" placeholder="Enter First Name" required>
</div>
<div class="form-group">
<label for="contactUsLastName">Last Name</label>
<input type="text" class="form-control" id="contactUsLastName" placeholder="Enter Last Name" required>
</div>
<div class="form-group">
<label for="contactUsEmail">Email</label>
<input type="email" class="form-control" id="contactUsEmail" placeholder="Enter Email" required>
</div>
<div class="form-group">
<label for="contactUsMessage">Message</label>
<textarea class="form-control" id="contactUsMessage" placeholder="Enter Message" required></textarea>
</div>
<div class="contactUsSubmitBtnCon"><button type="submit" class="btn btn-primary contactUsSubmitBtn" onclick="proccessContactMessage()">Submit</button></div>
</form>
Upvotes: 0
Reputation: 196
The no-cors
mode doesn't support the Content-Type: application/json
header. Try to set up a CORS header and remove the mode: 'no-cors'
property.
Upvotes: 1
Reputation: 571
Remove mode: 'no-cors'
from the options
.
This should give you the desired result.
Upvotes: 3