Netlify Web App x Netlify Express App gives - CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource

Hey everyone,

I’m having a problem when trying to set up my API on a Netlify server.

This API is perfectly working on postman but not on my web app published on Netlify.

This are the codes:

netlify.toml

[build]
    functions = "functions"

[[headers]]
  # Define which paths this specific [[headers]] block will cover.
  for = "/*"
    [headers.values]
    Access-Control-Allow-Origin = "*"

api.js

const express = require('express');
const serverless = require('serverless-http');
const mysql = require('mysql')
const app = express();
const router = express.Router();
const cors = require('cors')

//Get all students
router.get('/', (req, res) => {
  res.send('App is corriendo...');
});

const db = mysql.createPool( {
	host: 'xxxxxx',
	user: 'xxxxx',
	password: 'xxxxx',
	database: 'xxxxx'
})

let users = [
	{
		id: 1,
		nombre: "Juan"
	}
]

router.get("/users", (req, res) => {
	res.json(users)
})

router.get("/info", (req, res) => {
	const sqlSelect = "SELECT * FROM contacto"
	db.query(sqlSelect, (err, result) => {
		if(err){
			res.send("error")
		} else {
			res.send(result)
		}
	})
})

router.post('/enviarmensaje', (req, res) => {

	console.log("hey")

	const nombreContacto = req.body.nombreContacto
	const apellidoContacto = req.body.apellidoContacto
	const correoContacto = req.body.correoContacto
	const asuntoContacto = req.body.asuntoContacto
	const mensajeContacto = req.body.mensajeContacto

	const sqlInsert = "INSERT INTO `contacto` (`id_contacto`, `nombre`, `apellido`, `email`, `asunto`, `mensaje`) VALUES (NULL, ?, ?, ?, ?, ?);"
	db.query(sqlInsert, [nombreContacto, apellidoContacto, correoContacto, asuntoContacto, mensajeContacto], (err, result) => {
console.log(result)
	})
})

app.use('/.netlify/functions/api', router);
app.use(cors())
router.use(cors())
module.exports.handler = serverless(app);

And finally the client-side:

const enviarMensajeContacto = (event) => {
        event.preventDefault();

        Axios.post("https://bellumserver.netlify.app/.netlify/functions/api/enviarmensaje", { nombreContacto: nombreContacto, apellidoContacto: apellidoContacto, correoContacto: correoContacto, asuntoContacto: asuntoContacto, mensajeContacto: mensajeContacto }).then(() => {
            alert("bien")
            setPosts([nombreContacto, res.data])
        }).catch(e => {
            console.log(e)
        })
    }

I’m using cors on the server and added the header to the netlify.toml

I don’t know what else to do. Thanks for your time.

Can you provide a URL where the error is seen?

Sure, at bellumcoaching.com

At the “Contacto” page

When you press the submit button

I entered random data into the form and clicked submit. Watching the console I see the CORS error. I also see in the response body:

errorMessage	"2023-04-24T22:50:18.405Z 35dcecbe-9a9e-4b03-94ae-2bdd7ee56d7a Task timed out after 10.01 seconds"

So the function is not completing in the execution limit thus the return does not contain the Access-Control-Allow-Origin header, hence the CORS issue.

So you’ll need to investigate why the function is not completing in the execution time limit.

Thanks, I saw the timed out thingy too. I don’t really know if this should work like this, but on the api.js file, I never get the console.logs. Maybe that’s a hint?

This is the updated api.js function that sends the contact form

router.post('/enviarmensaje', (req, res) => {

	const nombreContacto = req.body.nombreContacto
	const apellidoContacto = req.body.apellidoContacto
	const correoContacto = req.body.correoContacto
	const asuntoContacto = req.body.asuntoContacto
	const mensajeContacto = req.body.mensajeContacto

	console.log("hey")
	console.log(nombreContacto, apellidoContacto, correoContacto, asuntoContacto, mensajeContacto)

	const sqlInsert = "INSERT INTO `contacto` (`id_contacto`, `nombre`, `apellido`, `email`, `asunto`, `mensaje`) VALUES (NULL, ?, ?, ?, ?, ?);"
	console.log(sqlInsert)
	db.query(sqlInsert, [nombreContacto, apellidoContacto, correoContacto, asuntoContacto, mensajeContacto], (err, result) => {
console.log(result)
	})
})

If the function is called, technically you should see anything that is logged to console.

Have you updated the function? If so the result is the same.

You might need to log out the err in the db.query as it is likely this that will provide clues to a solution.

Yeah, I pointed out the error like this

db.query(sqlInsert, [nombreContacto, apellidoContacto, correoContacto, asuntoContacto, mensajeContacto], (err, result) => {
console.log(result)
	}).catch(
		console.log(err)
	)

Now the CORS error disappeared magically xD. But not a new one appears. Code 500. Feel free to test by yourself but its this one:

Again, the Response shows the reason for the error

The catch is wrong.

Yeah mb. The new error was coming because db.query doen’t have a .catch function. My bad. It’s an axios problem

No it doesn’t.

Also looking at the post function again

it doesn’t return anything which likely explains the timeout error previously received.

Ah, I see.

Sorry for this question, I’m a newbie on this.

How do I add the return?

I came up with this:

const sqlInsert = "INSERT INTO `contacto` (`id_contacto`, `nombre`, `apellido`, `email`, `asunto`, `mensaje`) VALUES (NULL, '0', '0', '0', '0', '0');"
	console.log(sqlInsert)
	db.query(sqlInsert, (err, result) => {
		return 200;
	})

But I guess you will maybe know better…

I also updated the client to this:

const enviarMensajeContacto = (event) => {
        event.preventDefault();

        const headers = {
            'Content-Type': 'text/plain'
        };


        // Axios.get("https://bellumserver.netlify.app/.netlify/functions/api/users").then(data => {
        //     console.log(data)
        // }).catch(e => {
        //     console.log(e)
        // })

        let baseURL = "https://bellumserver.netlify.app/.netlify/functions/api/enviarmensaje";

        let config = {
            timeout: 10000,
            headers: { 'Content-Type': 'application/json' }
        };


        var data = { nombreContacto: nombreContacto, apellidoContacto: apellidoContacto, correoContacto: correoContacto, asuntoContacto: asuntoContacto, mensajeContacto: mensajeContacto };

        Axios.post(baseURL, data, config)
            .then((res) => {
                console.log("RESPONSE RECEIVED: ", res.data);
                return {
                    statusCode: 200,
                    body: JSON.stringify({ title: "this was a success" }),
                };
            })
        console.log(nombreContacto, apellidoContacto, correoContacto, asuntoContacto, mensajeContacto)
    }

Forgot to mention. If I click on submit or send a post on postman, it now returns always the timeout code, but it inserts the info to the database.

I suggest start by looking at the Express Response documentation (if that is what is handling this as I suspect it is.)

The return demonstrated in the last piece of code above is correct for a serverless lambda function, but this is only returned to Axios.post—the outer function is never returning this return.