I have a nodejs code where the user initially is in the localhost:3000/index
once the code starts, the page /index
has a form, once user clicks submit button he gets redirected to another page localhost:3000/process
there is a POST request (in script.js
file) that sends those data to server, then the POST
request on the server
side needs to execute a function
, only once the function (which is inside the POST request is executed)then I would like the user to be redirected to another page localhost:3000/done
res.render('done')
and res.redirect('/done')
at the end of the post request are not working..
I have tried many things, but still not able to be redirected once the function inside the post
request is executed.
the structure of my project is like this:
public folder structure:
js_folder:
script.js
routes folder:
index.js
process.js
done.js
views folder:
index.ejs
process.ejs
done.ejs
app.js file
****** ******* ******* *** ****
this how the process.js file looks like:
const express = require('express');
const router = express.Router();
/*once the user clicks on submit button (in the localhost:3000/index page) he is redirected */
router.get('/process', async (req, res) => {
// this process.ejs is showing 'please wait until function is executed'
res.render('process')
});
router.post('/process', async (req, res) => {
// getting data sent by the form
var data = req.body;
const functionOne = async function firstFunction() {
//do something
}
const secondFunction = async () => {
const update = await functionOne()
console.log('something is done');
// now I would like to redirect the user to the 'localhost:3000/done'
}
secondFunction();
});
/****** *************************** **********/
the script.js file:
function launchTerraform() {
var data = {
instances: document.getElementById('firstName').value,
region: document.getElementById('lastName').value
}
var xhr = new window.XMLHttpRequest()
xhr.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200 && this.responseText) {
}
}
xhr.open('POST', '/provision', true)
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
xhr.send(JSON.stringify(data))
window.location.href = '/process'
}
CodePudding user response:
Your server function could simply send an empty response (with status 200) after the asynchronous function has completed.
router.post('/process', async (req, res) => {
var data = req.body;
const functionOne = async function firstFunction() {
//do something asynchronous with data
}
await functionOne();
res.end();
});
Then your client script could tell the user to wait before making an XHR to /process
and perform the redirect to /done
after the status 200 response has come in.
xhr.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
window.location.href = '/done';
}
};
document.getElementById("some_placeholder").textContent = "Please wait ...";
xhr.open('POST', '/process', true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.send(JSON.stringify(data));
CodePudding user response:
You can only send one response.
A workaround for this is using express-flash to display the "please wait" message, and then once it is done you can use your 1 response to redirect the user to the "/done" page by doing res.redirect("/done")
. But that requires you use passport and cookie-parser.