I am developing a NodeJS / ExpressJS application on my computer. I have node running locally. I have a single page web app. When it needs information it makes ajax requests with jQuery.
The problem is when I have multiple requests for different sets of data. Node/express will start processing the first request and then the second request comes in before the first request has been fulfilled, it sends the response to the second request from the first request instead of sending it to the first request like it is suppose to. If I put a pause ( using an alert ) in my app so that is slows it down so the next request doesn't get sent until the first request was fulfilled, everything works fine.
I don't understand why this is happening. I thought node / express was suppose to be able to handle this and keep the requests separate.
Also, I get a "Can't set headers after they are sent" error in node because it is apparently merging the requests....
Here is what happens
ajax request 1 -> server
ajax request 2 -> server
ajax request 3 -> server
server -> request1 ( no response )
server -> request2 ( request 1's data)
server -> request3 ( request 2's data)
server for request3 --> error: header's already sent
I am using Google Chrome 63 with jQuery 3.3.1 on a Windows 10 machine running Node 8.9.4 and Express 4.16.2
My work-around is to chain the ajax requests so that each request doesn't get called until the prior request has received a response from the server. But I shouldn't have to do that...
Here is the relevant server code:
var mysql = require("mysql");
var express = require('express');
var app = express();
var DEBUG = true;
var request = null;
var response = null;
var currentDataRowParser = null;
var con = mysql.createConnection(config);
function ParseMySqlRowData(rowData)
{
if (DEBUG) console.log("ParseMySqlRowData");
return JSON.stringify(rowData);
}
var ParseMySqlRowsDatatoResponse = function (err, rows)
{
if (DEBUG) console.log("ParseMySqlRowsDatatoResponse");
var MySQLRows;
try
{
if (!err)
{
MySQLRows = "[";
for (var i = 0; i < rows.length; i++)
{
if (i > 0)
MySQLRows += ", ";
MySQLRows += currentDataRowParser(rows[i]);
}
MySQLRows += "]";
if (DEBUG) console.log("write rows");
if (DEBUG) console.log(MySQLRows);
response.send(MySQLRows);
response.end();
}
}
catch (ex)
{
if (DEBUG) console.log("ParseMySQLRowsDatatoResponse: ERROR");
if (DEBUG) console.log(ex);
}
};
var GetQueryData = function (query, dataRowParser, parseDataCallbackFunction)
{
if (DEBUG) console.log("GetQueryData");
currentDataRowParser = dataRowParser;
if (parseDataCallbackFunction == null || parseDataCallbackFunction == undefined)
parseDataCallbackFunction = ParseDataCallback;
try
{
if (DEBUGQUERY)
{
console.log("before query");
console.log(con.query(query, parseDataCallbackFunction));
console.log("after query");
console.log(query.sql);
DEBUGQUERY = false;
}
else
{
con.query(query, parseDataCallbackFunction);
}
}
catch (ex)
{
console.log(ex);
}
};
app.post('/getdata', function(req, res)
{
request = req;
response = res;
var query;
switch (request.body.loaddata)
{
case "dataset1":
query = "SELECT * FROM table1 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
case "dataset2":
query = "SELECT * FROM table2 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
case "dataset3":
query = "SELECT * FROM table3 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
}
};
the second request comes in before the first request has been fulfilledJavaScript is executed asynchronously . If you want more explanation we need to see your coderequestandresponseas global variables. Ever. Handle everything in the scope where they're called, not globally.reqandresfrom theapp.posthandler and using that in your callback chain vs. the global vars.