405 (Method Not Allowed) - PUT - node.js

I am currently taking a NodeJS course and learning GraphQL.
The course instructed to set header on the server side like this:
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Methods',
'OPTIONS, GET, POST, PUT, PATCH, DELETE'
);
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
However it keeps giving me a
App.js:122 PUT http://localhost:8080/graphql 405 (Method Not Allowed)
error.
I tried looking at the video multiple times and looking around for answers but found no luck.

Setting the response header Access-Control-Allow-Methods: ..., PUT, ... tells the browsers to allow cross-origin clients, i.e. a 3rd-party website from another domain, to send PUT requests to your backend service. This has nothing to do with the error response 405 (PUT) Method not allowed.
The error 405 (PUT) Method not allowed is returned by your Nodejs app because there is no actions to handle PUT requests to that path in your code.
GraphQL libraries typically use POST. Try sending POST requests to your GraphQL endpoint instead of PUT.

Related

How to solve CORS error in NodeJS independent of CORS middleware

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.
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-Language and Content-Type.
Content-Type can only be application/x-www-form-urlencoded, multipart/form-data or text/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.
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();
});

CORS was working fine but suddenly stopped working?

This is what I have in Node:
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200/');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
My front-end is in Angular. Everything was working just fine, but all of a sudden I started getting CORS errors. When I check the console, I get this:
The Initiator Context and the Allowed Origin are exactly the same. And, as I mentioned before, I was having 0 issues until all of a sudden it decided to stop working. So I don't understand what's going on here. Any help will be appreciated.
You can try with http://localhost:4200, without the last '/'

CORS policy issue

I am in a team doing a client-server application. We are using Node.js (v12.18) in the backend as an API, and React (v16.13) for the frontend. Recently I've found this bug related to the CORS policy. I'm trying to send a POST request, deleting one resource in the database and when trying to delete it, this is the error I get:
Access to fetch at 'http://localhost:8080/clientes/eliminar' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
As far as I researched in forums and discussions I always find the same resolution, which is using the "Access-Control-Allow" headers, but we are already using them. I tried to change the POST method by a DELETE method when doing the request, but I find the same issue.
The headers that we are currently using in the backend, in case someone wonders what we have.
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
next();
});
The sites I visited in order to solve the problem were pretty much the same as this one
TYSM for reading until here and ask for more information you need. Every piece of help is appreciated.
Have you already tried to add CORS to the project and use it as a middleware?
//...
const cors = require('cors')
//...
app.use(cors())

Access to XMLHttpRequest problems with Cors

I took an Ionic 5 course and when I did one of the exercises I wanted to put the backend written in JS inside github and heroku, when starting my authentication within my application it throws me the following error:
error
my backend is en node and express:
//allow cross config
server.app.use( cors({ origin: true, credentials: true }) );
server.app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'x-token, content-type');
next();
});
my app need to login and return one token per user, and this token is use in headers in other petitions
To avoid CORS issues i think you should use native http requests in your ionic app.
That is the simpliest way to solve your issue in my point of view.

Failed to load 'endpoint': Request header field If-Modified-Since is not allowed by Access-Control-Allow-Headers in preflight response

I have created one API service using nodejs and it is working fine when I accessing through the browser. But when I'm try to call it from web application (MEAN app), getting the "Failed to load http://localhost:2020/api/posts: Request header field If-Modified-Since is not allowed by Access-Control-Allow-Headers in preflight response" issue.
Following code is added in index.js of the API service.
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
and added following lines in controller of the web app,
app.config(["$routeProvider", "$httpProvider", function ($routeProvider, $httpProvider) {
$httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = '*';
}
]);
But no luck for added the above lines. How to resolve this issue ?
Thanks.
You need to add If-Modified-Since to Access-Control-Allow-Headers in your server code:
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,If-Modified-Since');
Also the part where you touch HTTP header on client seems useless to me, I don't think you can do anything with that.

Resources