Express enabling CORs headers still cause errors - javascript

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);

Related

Express.js CORS configuration, PUT does not work?

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', '*');

How to fix CORS error with credentials: include?

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",

Cross origin requests are only supported for protocol schemes. Node.js server Angular front end [duplicate]

This question already has an answer here:
CORS Error: “requests are only supported for protocol schemes: http…” etc
(1 answer)
Closed 3 years ago.
Im trying to enable CORS on a localhost site for a Node.js server with an Angular client.
I keep getting:
Access to XMLHttpRequest at 'localhost:3000/api/v1/users' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
I've tried:
app.use(cors())
the app.use function from here: https://enable-cors.org/server_expressjs.html
the specific app.use function from here with origin='localhost:4200'
the app.use function with origin='*'
My current node server.js file:
const express = require('express')
const app = express()
const cors = require('cors');
const port = 3000
///////
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
///////
app.get('/*', (request, response) => {
response.send('Hello from Express!')
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
My Angular method that is calling the node route (I know this is working because I get the cors error in chrome console shown above):
this.http.get<string[]>('localhost:3000/'+'api/v1/users').subscribe(x=>this.data=x);
For testing you should use a CORS browser plugin. The benefit of this is, that you dont have to modify the code when you want to build the code for prod

CORS on server header

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) => {...}

How to use REST with Node.js and AngularJS being on different port?

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();
});

Categories

Resources