-1

I am having a weird issue. I get cors error for put request on browser:

Access to fetch at 'http://localhost:3015/pathtest/api/v1/results/cc7637578fad1a6fcfb4249fbf000a13/load' from origin 'https://localhost:9444' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

And here is my code to enable cors in backend(nodejs). All the other api requests have been fixed with the below code and only put still returns cors issue:

app.use(function(req, res, next) {
  // res.header("Access-Control-Allow-Origin", "*");
  // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  // res.header('Access-Control-Allow-Methods', 'PATCH, PUT, POST, GET, DELETE, OPTIONS');
  //     // allow preflight
  //     if (req.method === 'OPTIONS') {
  //       res.send(200);
  //   } else {
  //       next();
  //   }

  res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
// allow preflight
if (req.method === 'OPTIONS') {
    res.send(200);
} else {
    next();
}
});

Am I missing anything?

**Update

enter image description here

Learner
  • 1,686
  • 4
  • 19
  • 38
  • Can you show the code for the PUT request so we can see everything that is part of it? – jfriend00 Nov 20 '19 at 04:50
  • I wonder if `Access-Control-Allow-Origin: *` is not acceptable for an OPTIONS pre-flight (that you need to list the explicit requesting origin)? I seem to remember reading something about that at one point, but I haven't put my hands on a reference that says that yet. I did find a reference that says `Access-Control-Allow-Origin: *` is not acceptable for "credentialed requests", but I'm not yet sure exactly what makes a request credentialed. – jfriend00 Nov 20 '19 at 04:54
  • Are you sending a cookie with the request? If so, that makes it credentialed and you may also need `Access-Control-Allow-Credentials: true`. – jfriend00 Nov 20 '19 at 05:26
  • @jfriend00 Thanks Jeff, I tried to ignore Access-Control-Allow-Origin: * on option but the same result – Learner Nov 20 '19 at 14:06
  • @jfriend00 Added but the same issue: Access-Control-Allow-Credentials: true – Learner Nov 20 '19 at 14:07
  • @jfriend00 I do not unfortunately have access to the client code but the above is my server code trying to handle the request – Learner Nov 20 '19 at 14:07
  • Well, we need to see the whole incoming request then to see exactly what it has in it (all headers). – jfriend00 Nov 20 '19 at 14:08
  • @jfriend00 Please see the update I attached all the headers – Learner Nov 20 '19 at 16:55
  • I don't see any of the `Access-Control-Allow-xxx` headers in that. – jfriend00 Nov 20 '19 at 17:01
  • @jfriend00 Please check it now – Learner Nov 20 '19 at 17:26
  • Please show the whole headers, including the actual values. In the response in the screen shot, I'm not seeing the result of this `res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');` or this `res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');` so it appears your middleware is not working properly. – jfriend00 Nov 20 '19 at 17:36
  • FYI, lots of sample CORS back and forth examples with full request/responses here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS. Worth looking at the pre-flighted requests in that page. – jfriend00 Nov 20 '19 at 17:43
  • @jfriend00 Actually the problem is I do not see any put req sent and as soon as Option returns I see cors so I do not see any request sent for put to be able to grab the response...What I posted above is whats returning from option request before sending put request. But this only happen to put and works for other reqs then how could it be a middleware issue? – Learner Nov 20 '19 at 17:44
  • That's because your server's pre-flight response does not have the required information in it to allow the browser to send the actual PUT request so the CORS request is blocked by the browser. The middleware you show in your question is apparently NOT what is responding to the pre-flight request because those headers don't show in the pre-flight response screenshot you show. One wild suggestion would be to clear the browser cache. – jfriend00 Nov 20 '19 at 17:45
  • You could have some other middleware that is handling the OPTIONS request so this middleware never gets executed on the OPTIONS request. – jfriend00 Nov 20 '19 at 17:49
  • @jfriend00 so installing other middleware for handling the options? do you know any good one I can try? – Learner Nov 20 '19 at 17:51
  • I'm saying you DON'T want other middleware for handling the OPTIONS request. For example, do you have `app.use(cors())` in your code? If so, that will interfere. You want your middleware to execute, not some other. Put a `console.log("in CORS middleware", req.method)` in the middleware you show in your question. See if that gets output to the console when you try your request? – jfriend00 Nov 20 '19 at 17:54
  • @jfriend00 Thanks for your help your last comment fixed my issue. If you answer as a post I will accept it for others if they face the same issue – Learner Nov 22 '19 at 15:28

1 Answers1

2

From both of our investigation through comments, we've figured out that this was the cause of your problem...

The screenshot you show illustrates that the middleware code you show in your question is not handling that request. That apparently means you have some other middleware before it that is taking over the request and that one is not doing what you want so it's getting in the way of the middleware you do want to handle the request.

If, in your search for a solution, you've put something like app.use(cors()) (or some other code that attempts to handle CORs requests) into your code and that's before your own custom middleware, then it getting in the way of your own middleware. Remove that other CORS-related middleware so your custom middleware can get unimpeded access to the incoming requests and can do its job.

Remember that middleware and other request handlers are run in the order they were registered and if a given handler sends a response and does not call next(), then no more request handlers/middleware in the chain will get to act on that request.

jfriend00
  • 683,504
  • 96
  • 985
  • 979