I have a Node.js(v20.10.0
) backend server using Fastify(v4.26.2
) as the framework.
I have index.js as an entry point.
import Fastify, { FastifyInstance, FastifyServerOptions } from 'fastify';
import cors from '@fastify/cors';
// Assuming other settings and configurations are already written.
fastify.register(cors, {
origin: "https://dev.example.com",
credentials: true,
});
I have a GET
API called for listing users https://api-dev.example.com/api/v1/users
working fine.
But the issue comes with POST
API, where I can create a user https://api-dev.example.com/api/v1/create-user
.
When using any POST
API, I am getting CORS Error
Access to XMLHttpRequest at 'https://api-dev.example.com/api/v1/create-user' from origin 'https://dev.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests
I tried multiple approaches and still got the same error.
fastify.register(cors, {
origin: "*",
credentials: true,
});
By the error, I can understand that the OPTION
request is getting
in response headers Access-Control-Allow-Origin: *
that's why I am getting this error.
But in all GET
API response headers Access-Control-Allow-Origin: https://dev.example.com
I am not sure why the OPTION
request before the POST
request Access-Control-Allow-Origin
is *
If your GET request is working fine, but you encounter issues with POST or PATCH requests, then according to your error
Access to XMLHttpRequest at 'https://api-dev.example.com/api/v1/users' from origin 'https://dev.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests
This error indicates that the browser is sending an OPTIONS request to the server with the 'Access-Control-Allow-Origin' header set to wildcard '*', while your server only accepts specific origins.
The reason behind this is that every POST and PATCH request initiates a preflighted request. Unlike simple requests, for "preflighted" requests the browser first sends an HTTP request using the OPTIONS method to the server to determine if the server is opting in to receiving a cross-origin POST or PATCH request from server
to fix this you can try adding, optionsSuccessStatus: 200 in your cors options like shown below
fastify.register(cors, {
origin: "https://dev.example.com",
credentials: true,
optionsSuccessStatus: 200,
});
With optionsSuccessStatus: 200
, the server responds with a 200 OK status code for successful preflight requests.
This indicates to the browser that the server is configured to accept cross-origin requests.
Now that the server has acknowledged the successful preflight requests, your POST and PATCH methods should function correctly without encountering CORS-related issues.
edit: well one thing I noticed
since POST or PATCH request will trigger a preflight request with OPTION method
I noticed without optionsSuccessStatus: 200
in the chrome network tab
For the OPTIONS method, the request header had Access-Control-Allow-Origin: "*"
, whereas for the POST method, the request header had Access-Control-Allow-Origin: "https://dev.example.com"
.
and this is what the CORS error says in this case
Access to XMLHttpRequest at 'https://api-dev.example.com/api/v1/users' from origin 'https://dev.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests
After adding optionsSuccessStatus: 200
to the configuration, both the OPTIONS and POST requests had the request header Access-Control-Allow-Origin: "https://dev.example.com"
. In this case, the OPTIONS method also had the header Access-Control-Allow-Origin: "https://dev.example.com"
instead of the wildcard *
as it did previously.
so for this, we have to take care!