Another question about CORS, I looked through a lot of information, but couldn't do anything. So I will be grateful for the help.
I am sending a fetch request with credentials enabled. What the browser regularly swears on at Access-Control-Allow-Credentials. I tried to configure a proxy, but it also does not work with it. So I need to add Access-Control-Allow-Credentials in response settings on the server. But I don't realize how.
I'm using create-react-app. There is not even a file with the familiar server code
error:
The value of the 'Access-Control-Allow-Credentials' header in the response is ''
which must be 'true' when the request's credentials mode is 'include'
Response headers:
access-control-allow-origin: http://localhost:3000
Request headers:
WARNING Provisional headers are shown
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-origin
Access-Control-Request-Method: GET
Origin: http://localhost:3000
Referer: http://localhost:3000/
Hi use the following code in your server.js or app.js in node.
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
app.all('*', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");```
If your backend is using Express, try to add this piece of code below:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', true);
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});
Another solution, you can use cors module, just basically install it:
npm install cors --save
And add this code in your server:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
Since you're using create-react-app the easiest thing to do is to use a proxy so that the request looks like it is coming from the same domain and avoid CORS altogether. Assuming your backend server will be on the same host, this is actually closer to production as well.
Webpack has a clean way to do this. See this blog by facebook: https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development
This has gotten incredibly easy to do now. All you need to do is add a proxy field to your package.json. For example -
"proxy": "http://localhost:4000",
Related
I have a website that fetches some JSON data from a heroku server I set up. I'm getting a CORS error and I'm not sure how to resolve it.
I am requesting it from a url, let's say, https://www.example.com/content/?id=12345
In my heroku endpoint, I have code that looks like this:
res.set("Access-Control-Allow-Origin", ["https://www.example.com"]);
But I still get this error that says the origins don't match:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at
https://mysterious-hamlet-72124.herokuapp.com/5iucwuFiaK1nJqWwfSHt.
(Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘https://example.com’).
Right now, I just set it to:
res.set("Access-Control-Allow-Origin", ["*"]);
and it works, but I'd like to know how to do it right.
Edit: Thanks for catching my typo...Dang do I feel stupid. I forgot to add "www" on my server-side, like the comments below said.
can you try below code in server side and it will resolve cors issue
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.configure(function() {
app.use(allowCrossDomain);
});
You can use the cors npm package
and add this code to your app.js (or whatever is your main file)
const cors = require("cors");
...
app.use(
cors({
origin: "Your front-end domain",
})
);
this works for me.
But if you want to know more about what CORS is I suggest you Mozilla developer guide
I have a React application and Nodejs(Express) in the Backend. After deploying to the host server, The function I did for updating some documents stop working properly. It gives the CORS error:
I have this line of code to handle CORS policy in my server.js:
app.use((req, res, next) => {
res.set({"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "HEAD, OPTIONS, GET, POST, PUT, PATCH, DELETE",
"Access-Control-Allow-Headers" : "Content-Type, Authorization, X-Requested-With"})
next();
});
It is ok for GET and POST methods but does not work for PUT (Don't know if Delete works haven't tried)
I am on this issue for plenty of time; tried this: https://stackoverflow.com/a/42463858/11896129
looked for a bunch of solutions on the net, tried to configure it from IIS web.config file, nothing resolve my problem. Which part may I miss?
As stated on MDN:
Additionally, for HTTP request methods that can cause side-effects on server's data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method.
So you do have to answer preflight requests:
app.options("*", (req, res) => {
res.status(200).send("Preflight request allowed");
});
Read more about preflight requests here.
This should work, I used this CORS configuration
app.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, PATCH");
res.header("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization, X-Requested-With");
next();
});
Most likely the error No 'Access-Control-Allow-Origin' header is present that you see is coming from the preflight OPTIONS request, which is most likely not even reaching your express backend but is being hanlded by webserver in the front.
Either arrange for OPTIONS requests also to be relayed to your express backend in your webserver configuration or instruct the webserver to respond to it with required headers.
Check these:
https://support.plesk.com/hc/en-us/articles/115001338265-How-to-set-up-CORS-cross-origin-resource-sharing-in-Plesk-for-Linux-
https://support.plesk.com/hc/en-us/articles/360005431913-Is-it-possible-to-enable-CORS-cross-origin-resource-sharing-on-Plesk-for-Windows
https://talk.plesk.com/threads/iis-cors-configuration-problem-for-node-js-backend.355677/
You can use npm package cors (https://www.npmjs.com/package/cors) in your project. Install it and then configure it as a middleware. And put it before your application routes.
const cors = require("cors");
const corsOptions = { origin: "*", methods:
"GET,HEAD,PUT,PATCH,POST,DELETE", allowedHeaders:
"Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Origin,Cache-Control,Content-Type,X-Token,X-Refresh-Token", credentials: true, preflightContinue: false,
optionsSuccessStatus: 204 };
app.use(cors(corsOptions));
Please try with below configuration
const cors = require('cors');
app.use(cors())
Please let me know if works for you or not.
See the Github repo for more info: https://github.com/expressjs/cors
We can use npm package to enable this too
npm install --save cors
After package is in place, use it as middleware as follows.
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
If you have requirement to confine your resource access to single application, that can be done as following
app.use(cors({
origin: 'http://yourapp.com'
}));
If you have requirement to add access to multiple applications, that can be done as follows
var allowedOrigins = ['http://localhost:3000',
'http://yourapp.com'];
app.use(cors({
origin: function(origin, callback){
// allow requests with no origin
// (like mobile apps or curl requests)
if(!origin) return callback(null, true);
if(allowedOrigins.indexOf(origin) === -1){
var msg = 'The CORS policy for this site does not ' +
'allow access from the specified Origin.';
return callback(new Error(msg), false);
}
return callback(null, true);
}
}));
Did you write middleware that attaches header before the line of code that handles PUT request? I have a similar code but it worked for me.
Another approach is to use npm 'cors' module.
For testing purpose, you can attach below test (you can attach the specific headers/methods later):
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', '*');
res.header('Access-Control-Allow-Methods', '*');
I am deploying a simple node server and a React app to Netlify. The React App makes an API request to the server, and uses cors via const cors = require("cors"); in version 2.8.5.
At first I specified the following (server.js)
app.use(
cors({
origin: CLIENT_ORIGIN
})
);
which only seems to tell the server "I am using CORS," but does not specifically set any headers or permit any whitelisted websites to access the server. I then set the CLIENT_ORIGIN in a .env file in my dev environment, and via the Build environment variables on Netlify. I deployed a new built for both the server and front-end, however I must have gotten it wrong somewhere:
Access to fetch at 'https://serverUrl.com/example/get' from origin
'https://react-app-example.com' has been blocked by CORS policy: 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.
I then tried setting:
app.use(function(req, res, next) {
res.header(
"Access-Control-Allow-Origin",
"https://react-app-example.com"
);
res.header("Access-Control-Allow-Headers", "Content-Type,Authorization");
res.header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE");
if (req.method === "OPTIONS") {
return res.sendStatus(204);
}
next();
});
which also did not work. The error message remained the same. The thing that irks me is that I have a similar from from a few months ago which is built very similarly, but stays on heroku. The same methods as described above work without problem.
What am I missing?
After trying various things I finally arrived at the fact that Netlify does not support Node apps by itself (without extra tedious config).
The closest solution can be found here in another answer or via another service like Heroku.
The major issue I have with heroku is that when the dyno (in my case the server providing API routes) doesn't get called for a while it goes to sleep to save resources, and in turn takes a whole lot longer to respond on the first call. Have not found any other free solution for node/express apps that serve API routes, yet.
UPDATE: Heroku and Netlify don't play along nicely unless you add the following CORS parameters to the backend:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", CLIENT_ORIGIN);
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE");
res.header("Access-Control-Allow-Credentials", true); <--- this is the only different line I added.
if (req.method === "OPTIONS") {
return res.sendStatus(204);
}
next();
});
And then the following to the front end request via fetch:
fetch(`${API_BASE_URL}/dept/get/`, {
method: 'GET',
credentials: 'include', <-- this is the most important change
})
.then((res) => {...}
Using the code provided by http://enable-cors.org/ for express I've added to my index.js file
/*these first five line direct from http://enable-cors.org/.com*/
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");
next();
});
var PORT = 3333;
app.listen(PORT, function(){
console.log('listening on port', PORT);
})
request({url: 'http://bl.ocks.org/mbostock/raw/4090846/us.json', json: true}, function(err, data){
app.get('/us', function(req, res, next){
console.log(req) //prints correctly
res.json(data.body);
});
});
localhost:3333/us shows the json correctly, but making a request from localhost:3000 (a port being served by browsersync) fails with the error
d3.min.js:1XMLHttpRequest cannot load localhost:3333/us. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
Is this no longer the correct way to enable CORS for localhost on express? I've also tried passing the app.use method '*' and '/us' as its first argument but no luck.
When making an Ajax call, you need a fully qualified URL with the protocol in it. This is not a legal URL:
localhost:3333/us
It is something you can type in the browser and the browser will automatically add a protocol to it (the browser does all sorts of things to try to make what you type in the URl bar into a legal URL, but that logic does not happen for requests made via Javascript and Ajax). Instead, change the URL to:
http://localhost:3333/us
I'd recommend just npm installing "cors" as a dependancy. Once you've done that just require and app.use it before all the routes you want to allow CORS.
// Dependancies
var cors = require('cors');
// Init express app
var app = express();
app.use(cors());
// Routes now allow cors
app.get('/api/endpoint', controllers.endpoint);
I am trying to understand the cooperation of Angular and Node.js on the backend. I can't figure out however, how to use REST for data transfer between the two.
I have:
Node.js backend running on port 8000, responding to various GET and POST requests (via cURL).
Angular frontend is loaded through Apache, running on port 80.
Naturally, the JavaScript console identifies it as not allowed by Access-Control-Allow-Origin.
How is this commonly solved? Am I doing it wrong? Should I not run the frontend through Apache?
One way to solve it is using Cross-origin Resource Sharing. Browser support is decent as well.
You can also do it using cors
npm install cors
const cors = require('cors');
app.use(cors({
origin: 'http://example.com'
}));
http://example.com is your application origin/domain at front-end side.
Add this to your Node.js API server
server.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if ('OPTIONS' == req.method) {
return res.send(200);
}
next();
});