I am facing a CORS error when trying to make a request from the client to a node server. I want to solve the issue independent of the CORS middleware. Here is the server-side code. Please let me know if I am missing something. Thanks.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers", "application/json");
res.send("<h1>Server is running at port 3000!<h1>");
});
app.listen(3000);
The error on the console:
Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
CodePudding user response:
The error message you get on the console says this:
Response to preflight request doesn't pass access control check
That means that the type of requests you are sending is not a "simple" request and requires server pre-flight. Pre-flight is where the browser sends an OPTIONS request with some details about the type of request it wants to send. The server then must respond to that OPTIONS request with the right CORs info before the browser will treat the request as approved and send the actual request.
To response to a pre-flight request, you must handle an incoming OPTIONS request (not a GET or POST or PUT, but OPTIONS). This is the browser asking your server if this request would be OK to send. You can read more about pre-flight requests here on MDN. And, you can read about the difference between simple requests and pre-flighted requests here on MDN.
To code your server to accept the pre-flighted request, you could do something like this:
app.options("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
res.sendStatus(204);
});
Depending upon what exactly the pre-flighted request is (what content-type, what method, etc...) you may need to specify additional options here. You don't show the code for the request in question here so we can't offer more specific details on that request.
Also, where you have this:
res.setHeader("Access-Control-Allow-Headers", "application/json");
that doesn't really make sense because "application/json" is a content-type, not a header. Perhaps you meant this:
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
Simple Requests
This is all spelled out in one of the above MDN references, but a Simple Request that does not require CORs pre-flight, meets the following criteria:
- Http method is GET, HEAD or POST
- Manually set headers on the request (apart from what the browser sets automatically) are no more than
Accept,Accept-Language,Content-LanguageandContent-Type. - Content-Type can only be
application/x-www-form-urlencoded,multipart/form-dataortext/plain
Any request that doesn't meet these simple rules will require pre-flight. So, for example, if you were setting the Content-Type to application/json, that would immediately cause pre-flight because that's not one of the permitted content-types for non-preflighted requests. If your request was a GET, then there's no need to set content-type at all since you aren't sending any content with the request.
CodePudding user response:
const corsOpts = {
origin: '*',
methods: [
'GET',
'POST',
],
allowedHeaders: [
'Content-Type',
],
};
app.use(cors(corsOpts));
OR you can use
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
