Building an API in Express and not able to fetch data?
Trying to submit a form via a POST request and getting CORS Pre-Flight errors in the console?
That can be frustrating - especially when you see an array of questions resolved by answers in Stack Overflow that don't seem to be working for you.
My issues began when I built a React frontend fetching data from an Express.js API. The React application sends both GET and POST http requests to the API and only now do I realize that the POST requests required an additional step.
Hey, Tyler here. I'm currently working on some great web development and digital marketing products and services over at ZeroToDigital.
If that sounds interesting to you, please check it out!
To fetch data via a GET request from Express to my React application, all I needed was a route middleware function that set the Access-Control headers for the page:
JavaScript
const headers = (req, res, next) => {
const origin = (req.headers.origin == 'http://localhost:3000') ? 'http://localhost:3000' : 'https://mywebsite.com'
res.setHeader('Access-Control-Allow-Origin', origin)
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE')
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type')
res.setHeader('Access-Control-Allow-Credentials', true)
next()
}
module.exports = headers
I would then simply reference the middleware in my route function:
JavaScript
router.get('/contact', headers, (req, res) => {
...
res.send(req.args)
})
Done. I could receive data all day with this setup. But the problem came with sending data back to the API with a POST request ...
What I learned was that certain CORS requests are considered "complex" and require an initial options request known as a pre-flight request. From my understanding, POST requests didn't fall within this categorization (DELETE requests are more common). However, my Express application did consider it to be complex and was therefore blocking it.
The simplest way to solve this and send a pre-flight request was via the CORS Node.js package (NPM ) - npm i cors and assigning it as middleware for the POST route:
JavaScript
const cors = require('cors')
router.post('/contact', cors(), headers, (req, res) => {
...
The headers middleware is still required to be sent along with the actual POST request. And this solved my issue.
The CORS module can be customized, but the default configuration worked in my case.
JSON
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
Hopefully this solved your problem. If not, reach out to me on Twitter below!