I have a Vue front end using axios to make http requests, and a Node back end using express. They are on different domains (when running locally, BE port is 3080 and FE port is 3000), and I am using the cors library in the Node backend to deal with CORS issues. In spite of preflight working, the post request still fails with a CORS error!
When I send a post request, the browser gets a beautiful 204 successful response for the preflight request, complete with these beautiful successful headers:
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: http://localhost:3000
Connection: keep-alive
Content-Length: 0
Date: Thu, 21 Apr 2022 03:25:54 GMT
Keep-Alive: timeout=5
Vary: Origin, Access-Control-Request-Headers
X-Powered-By: Express
So why does my POST request still fail with a CORS error?
Don't know if this is relevant, but it might be: I have tried this in both Brave (chromium based) and Firefox. Both of them have the same basic result, but with one difference: in Brave dev tools, it seems to show that the POST request was sent first, and then the preflight OPTIONS request. That would seem like an obvious red flag, BUT... in Firefox the dev tools show the preflight OPTIONS was sent first, followed by the POST. But as I said, the preflight succeeds and the post fails with a CORS error in both browsers.
CORS Error Screenshot (Firefox):

Back End Code
app.js:
const express = require('express');
const cors = require('cors');
const app = express();
const port = 3080;
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(cors());
app.options('/signup', cors());
app.post('/signup', (req, res) => {
res.status(200).json({ message: 'SUCCESS'}).send();
})
app.listen(port, () => {
console.log(`Listening on port ${port}`)
})
Front End Code
apiClient.js:
import axios from "axios";
const apiClient = axios.create({
baseURL: "http://localhost:3080",
headers: {
"Content-type": "application/json"
}
});
export default apiClient;
authService.js:
import apiClient from '../../../../common/utils/apiClient';
export const login = async (email, password) => {
return await apiClient.get(`/login?email=${email}&password=${password}`);
}
export const signup = async (user) => {
return await apiClient.post('/signup', user, {
headers: {
'Content-Type': 'application/json'
}
});
}
Script in SignUp.vue:
<script setup>
import { signup } from '../service/authService'
async function handleSignup(email, password) {
await signup(email, password);
}
</script>
