XHR failing to send JSON data to Express server

My goal is to transmit a JSON object to an express server. Below is the code I have written for the client side:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Express demo</title>
</head>
<body>
<button onclick="sendUrlEncoded()">Send an application/x-www-form-urlencoded POST request</button>
<button onclick="sendJson()">Send an application/json POST request</button>
<div id="response"></div>
<script>
function sendUrlEncoded() {
    var data = "text=stuff";
    var http = new XMLHttpRequest();
    http.open("POST", "http://127.0.0.1");
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.send(data);
}

function sendJson() {
    var data = {text:"stuff"};
    var http = new XMLHttpRequest();
    http.open("POST", "http://127.0.0.1");
    http.setRequestHeader("Content-Type", "application/json");
    http.send(JSON.stringify(data));
}

</script>
</body>
</html>

Here is the code for the server side implementation:

var express = require("express");
var path = require("path");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));

app.use(function(req, res, next) {
    console.log("Received request");
    console.log(req.headers);
    console.log(req.body);
    next();
});

app.get("/", function(req, res) {
    console.log("GET request");
    res.sendFile(path.join(__dirname + "/index.html"));
});

app.post("*", function(req, res) {
    console.log("Received post request");
    res.status=200;
});

var server = app.listen(3001, function() {console.log("Listening on port 3001")});

In a previous version of my code, the function sendJson() was named as "sendPost()". Upon testing, it was observed that when a GET request or XMLHttpRequest is sent from the client, the server always receives it successfully. However, there are some issues with the way the server handles different types of requests. When using sendUrlEncoded() or sending a GET request, the data is received by the server in the body and the app.get() function is called correctly. But, with sendJson(), the server only picks up the request in the general message handler. The app.get() function is not triggered and the request body shows {}. Furthermore, the header received is not as expected:

{
  host: 'xx.xxx.xxx.xxx:3001',
  connection: 'keep-alive',
  accept: '*/*',
  'access-control-request-method': 'POST',
  'access-control-request-headers': 'content-type',
  origin: 'http://192.168.0.102:3001',
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
  'sec-fetch-mode': 'cors',
  referer: 'http://192.168.0.102:3001/',
  'accept-encoding': 'gzip, deflate',
  'accept-language': 'en-US,en;q=0.9'
}

Note: For privacy reasons, I have replaced the actual IP address with xx.xxx.xxx.xxx. Any assistance would be greatly appreciated!

Answer №1

[Edited] It's crucial to remove the unnecessary middleware before defining the app.get endpoint in order to avoid any confusion or server hang-ups. Remember to properly end the request by sending the response back to the user, using either send or end. The main issue at hand arises from using a wildcard * for both post requests. It's recommended to use distinct endpoints for each of your requests.

Here is an updated version:

var express = require("express");
var app = express();
var bodyParser = require('body-parser');

// Setting up parsers for different content types

var jsonParser = bodyParser.json() // For application/json requests
var urlencodedParser = bodyParser.urlencoded({ extended: true })  // For x-www-form-urlencoded data

// Handling POST requests with specific content types

app.post('/urlencoded', urlencodedParser, function (req, res) {
    res.send('welcome, ' + JSON.stringify(req.body));
})

app.post('/', jsonParser, function (req, res) {
    console.log("Received post request for application/json type");
    console.log(req.body);
    res.send(JSON.stringify(req.body)).end();
})

app.listen(3001, function () {
    console.log("Listening on port 3001")
});

After making these changes, testing with application/json should yield the expected results, echoing back the request body.

You cannot set conflicting content-types for your requests. Stick to either application/json or x-www-form-urlencoded.

Does this address your concerns?

Answer №2

One issue I encountered was trying to access my server using a LAN IP instead of the necessary WAN IP. Additionally, I had mistakenly commented out app.use(bodyParser.json()). The former mistake caused problems with sending requests from the client, generating an error in the browser console. The latter error hindered express from properly receiving the JSON object within the request body.

To resolve these issues, I took the following steps:

In order to enable CORS functionality, I implemented the following code:

var cors = require("cors");
app.use(cors());

To ensure that Express can receive JSON data from application/json POST requests, I included the following code:

app.use(bodyParser.json());

For those new to programming like myself, I found this article to be quite informative on the topic of CORS.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue Arising from Inability to Activate Mongoose Pre/Post Hook During Document Deletion

Struggling with implementing pre and post hooks for document deletion in Mongoose. Tried different methods, from deleteOne to deleteMany, findOneAndDelete, and findOneAndRemove. Also experimented with modifying deleteOne middleware code to first find the d ...

Submitting data from a JavaScript frontend to a PHP backend

I've exhausted all options in attempting to resolve this issue. The javascript code is designed to send a list of product IDs to a PHP page. When products are selected, the submit button should activate the submit function. function submit() { ...

Sending parameters to ajax using a click event

I'm facing an issue with passing variables through Ajax to PHP. In a PHP file, I'm generating some divs with id and name attributes. livesrc.php echo "<div class=\"search-results\" id=\"" . $softwareArray['Sw_idn'] ...

Troubleshooting problem with Bootstrap file input on deployment

Having an issue with the Bootstrap file input package - it's working fine locally, but failing on production. Here is how it looks in VS And after deployment I've read that the problem might be with the js files not loading correctly, but I ha ...

What is the best way to retrieve and modify an AngularJS object within an array using its unique id value?

Let's say we have an array of objects: ctrl.items = [Object, Object, Object] Each object in the array follows this structure: {id:1, item:"item", quantity:2} These objects are displayed in the front-end using the following binding: <div ng-rep ...

Setting the initial viewer position in Panolens: A step-by-step guide

I've been working on setting the initial viewer position for panolens.js for a while now. Here's how the set-up looks: const panoPhoto1 = 'https://conceptcityiasi.ro/assets/images/tours/tip1/apartamente-noi-de-vanzare-iasi-dacia-1_camera-ti ...

What is the best way to format table values as currency?

Still getting the hang of Javascript, and I'm in the process of learning... Currently, my challenge involves calculating the total sum of values within a Bootstrap 4 table and formatting the result as currency (specifically in USD format). While I&ap ...

The Node.js REST API encountered an issue with the message "Unable to submit /api/v1/product."

I'm currently working on setting up a post method for a REST API using Node.js. I'm encountering an issue where Postman is saying "cannot post /API/v1/product," but there are no errors showing up in the console. Can anyone provide assistance with ...

nginx returns a 404 error for subpaths

I have successfully dockerized a Node.js application on an Ubuntu server using GitHub CI/CD. I've set up a reverse proxy with Nginx that works when I access the server's IP address directly. However, when I try to access something like serverip/a ...

URL-based authentication using Passport.js

I am currently working on my app using Express JS and Passport JS. My goal is to allow a new user to automatically log in once by accessing a specific URL. I have the ability to retrieve the user information from the database based on the URL provided, re ...

Sending a value to a specialized component

Presently, I am using a custom component called Search. This component is responsible for rendering a dropdown menu with different options based on the data provided. It also includes a None option by default. const Search = (props) => { const { type: ...

Step-by-step guide on implementing a foreach loop in conjunction with an AJAX call

I am encountering an issue with a foreach loop that is triggered by my AJAX code. It seems like the foreach loop is being skipped entirely. My goal is to have the foreach loop run a query using each value in the array. However, before implementing this fun ...

Having trouble fetching values in Node.js after a certain period of time has passed

Whenever the page loads, the sha1 function is supposed to run and it should run after 5 seconds. var crypto = require('crypto'); console.log(sha1()); setTimeout(sha1, 5000); console.log(sha1()); function sha1() { var dt = dateTime.create(); ...

Track and display the number of times a button is clicked using

I'm looking to create a button click counter that changes the text on the button when clicked. I want to write this information to a database as well, but I'm struggling with the implementation. <button type="button" class="btn btn-info" styl ...

Waiting for state changes in React by using the UseState Hook

I am currently working on a function that manages video playback when clicked, and I need to set consecutive states using the useState hook. However, I want to ensure that the first state is completed before moving on to the next setState without relying ...

Issue with e2e.js file format in Cypress Support

I am trying to save Cypress screenshots into a report using a support file as recommended in the documentation. However, I keep encountering an error: Your supportFile is missing or invalid: support/e2e.js The supportFile must be a .js, .ts, .coffee file ...

Utilizing Angular to parse a JSON string generated with json.dumps

I am having trouble finding a solution that works for me. Currently, I am using python 3.6 (Django Rest Framework) on the server side and Angular 5 on the client side. This is the code on the server: class TypesView(APIView): def get(self,request): ...

The value of req.headers.origin is consistently undefined, is there a way to grant access to various domains for ALLOW

I'm trying to implement Access-Control-Allow-Origin (CORS) and ALLOW-FROM (iframe) for multiple addresses, but I've encountered a problem. Despite researching solutions, such as this one on Stack Overflow, I can't seem to get the expected re ...

I am experiencing a problem with using the .focus() method with an input field

When my window loads, I want the cursor in this input to be blinking and ready for typing. I have tried using jQuery to make this happen, but for some reason I can't get the .focus() function to work properly. Check out my code on JSFiddle This is t ...

Unable to retrieve data from the database within PHP code

I have successfully built a shopping cart website utilizing SQL, HTML, and PHP. Below is the code snippet for the 'Add to Cart' button: <form method="post" action="cart.php" class="form-inline"> <input type="hidden" value="&apos ...