express icon indicating copy to clipboard operation
express copied to clipboard

POST request causing PreFlight and then getting cancelled after stalling

Open am-a-man opened this issue 2 years ago • 3 comments

I wrote a simple API for learning using express, when I try to send a POST request from POSTMAN it is carried out and returns a success message but when POST is sent from client, PreFlight is issued and POST request after being stalled gets cancelled, after which PreFlight does return "204 No Content" success message.

  1. PreFlight must not be issued during POST request ?
  2. if it does how to make sure it does that it does not stall the POST request, or how to increase the timeout for POST request?

my client side code is:

  button.onclick = addElement=> {
            var key = document.getElementById('key').value;
            console.log("button clicked");
            var value = document.getElementById('value').value;
        
            console.log(key);
            var options = {
                method : "POST",
                headers : {'Content-Type': 'application/json'},
                body : JSON.stringify({
                    'key':key,
                    'value':value
                })
            };
            console.log("initializing POST");
            const fet =  fetch('https://skiadrum.herokuapp.com/data', options).then(response => {
                console.log(response);
                return response.json();
            }).then(response => {
                console.log(response);
                document.getElementById('api_response').innerHTML = response;
            })
            .catch(error => {
                console.log("post request failed");
                console.error(error);
            });    

        }

and the server POST request handler is:

var postCorsOptions = {
	"origin": ['http://127.0.0.1:5500','http://127.0.0.1:5501'],
	"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
	"preflightContinue": false,
	"optionsSuccessStatus": 204,
    "Content-Type":"appllication/json"
}

app.post("/data", cors(postCorsOptions) , (request, response) => {
    var file = request.body;
    console.log(file.value);
    console.log("post request recieved in server");
    reply = {
        'status': 'success',
        'data_recieved' : {
            'key': request.body.key,
            'value': request.body.value
        }
    }
    score[request.body.key]=request.body.value;
    try{
        fs.writeFile('score.json', JSON.stringify(score, null, 2), err => {
            console.log("writing into the file from post request");
        });
    } catch(error){
        console.error(error);
    }
    
    response.send(reply);
});

am-a-man avatar Jun 09 '21 05:06 am-a-man

In your server-side code, why do you attach cors() as a middleware to the route and not as a global middleware in your server.js/index.js ?

what happens if you do something like this?

const cors = require('cors')
// other declarations

app.use(cors())
// other middlewares

app.post('/data', async (req, res) => { 
    // other logic
})

Aakash1103Jha avatar Apr 04 '22 12:04 Aakash1103Jha

@am-a-man I believe this issue occurs because the browser considers this request as complex and requires a pre-flight request, the browser sends this pre-flight request with method set to OPTIONS instead of POST. The documentation suggests how to deal with this.

Going through the Network tab in the browser dev tools might give a better idea of the HTTP headers of the options pre-flight request.

Johan511 avatar Jul 18 '22 07:07 Johan511

I wrote a simple API for learning using express, when I try to send a POST request from POSTMAN it is carried out and returns a success message but when POST is sent from client, PreFlight is issued and POST request after being stalled gets cancelled, after which PreFlight does return "204 No Content" success message.

  1. PreFlight must not be issued during POST request ?
  2. if it does how to make sure it does that it does not stall the POST request, or how to increase the timeout for POST request?

my client side code is:

  button.onclick = addElement=> {
            var key = document.getElementById('key').value;
            console.log("button clicked");
            var value = document.getElementById('value').value;
        
            console.log(key);
            var options = {
                method : "POST",
                headers : {'Content-Type': 'application/json'},
                body : JSON.stringify({
                    'key':key,
                    'value':value
                })
            };
            console.log("initializing POST");
            const fet =  fetch('https://skiadrum.herokuapp.com/data', options).then(response => {
                console.log(response);
                return response.json();
            }).then(response => {
                console.log(response);
                document.getElementById('api_response').innerHTML = response;
            })
            .catch(error => {
                console.log("post request failed");
                console.error(error);
            });    

        }

and the server POST request handler is:

var postCorsOptions = {
	"origin": ['http://127.0.0.1:5500','http://127.0.0.1:5501'],
	"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
	"preflightContinue": false,
	"optionsSuccessStatus": 204,
    "Content-Type":"appllication/json"
}

app.post("/data", cors(postCorsOptions) , (request, response) => {
    var file = request.body;
    console.log(file.value);
    console.log("post request recieved in server");
    reply = {
        'status': 'success',
        'data_recieved' : {
            'key': request.body.key,
            'value': request.body.value
        }
    }
    score[request.body.key]=request.body.value;
    try{
        fs.writeFile('score.json', JSON.stringify(score, null, 2), err => {
            console.log("writing into the file from post request");
        });
    } catch(error){
        console.error(error);
    }
    
    response.send(reply);
});
var postCorsOptions = {
	"origin": ['http://127.0.0.1:5500','http://127.0.0.1:5501'],
	"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
	"preflightContinue": false,
	"optionsSuccessStatus": 204,
    "Content-Type":"appllication/json"
}

You should put all the request methods in an array.

donoftime2018 avatar Nov 06 '23 20:11 donoftime2018