I have a Node/Express server that interacts with a React app.
I need to make POST and GET requests, the problem is that when making POST requests I get a CORS error, the usual:
Access to fetch at 'http://localhost:9000/testAPI' from origin 'http://localhost:3000' 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.
I specified on the response on the server the Access-Control-Allow-Origin header, but I am not sure if I have to set this header for a POST request as well. And if I do, what domain should it specify?
I am also not willing to use hacks like CORS extensions, or npm packages. I want to use CORS.
The server-side looks like so:
const express = require("express");
const router = express.Router();
router.get("/", (req, res, next) => {
console.log(req.url);
res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
res.send("API is working properly");
});
module.exports = router;
In the React app, the GET request looks like so (works just fine):
const res = await fetch('http://localhost:9000/testAPI');
console.log(res);
The POST request looks like so (CORS error thrown):
const res = await fetch('http://localhost:9000/testAPI', {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ someData: "POST requests are working properly" })
});
Do I need to specify some additional headers or properties on the POST request? Or do I have to modify something on the server-side?
If I will not have this problem when going live, than I do not mind using a hack like CORS extension.
You may use this package cors
// Install
npm install cors
yarn add cors
// server.js
const express = require('express');
const cors = require('cors');
const app = express();
// global middleware
app.use(cors());
// You can use route based middleware too
router.post("/", cors(), (req, res, next) => {
// process request & send response to client
});
First of all, i have an backend RESTapi running on my ubuntu server on the cloud(works perfectly 100%).
And I also have an frontend webapplication running on the same server(works perferctly aswell), and i can use the login system and all that stuff.
Now my issue: I am deploying the frontend locally at my computer for development purposes, but i still want to have the connection to my backend at the cloud instead of also deploying the backend locally.
Problem is now that when im using the authentication from my local computer i get this error:
Access to fetch at 'http://ip-adress-to-the-backend-at-the-cloud:5000/api/auth' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://*:3000' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The thing is: it worked perfectly logging in while using the webapp locally at my computer until last week.. Now that i made some changes in my ".env" file, "server.js" and "routes.js" file, it doesnt work.
The strange thing is that i tried removing the changes from those files but still aint working.
Here is my .env file:
APP_PORT=*****
DB_HOST=*****
DB_USER=*****
DB_PASSWORD=******
DB_NAME=******
JWT_SECRET=******
JWT_KEYSECRET=*******
ALLOWED_ORIGIN=http://ipadress_to_both_the_frontend_and_backend:3000
here is my server.js:
const express = require('express');
const app = express();
require('dotenv').config();
if(process.env.JWT_SECRET == undefined || process.env.JWT_KEYSECRET == undefined){
console.log("Fatal error: Secret is not set")
process.exit(1);
}
require('./startup/routes')(app)
require('./startup/database')
app.listen(process.env.APP_PORT, () => {
console.log("Server is running: " + process.env.APP_PORT);
})
and my routes.js:
require('dotenv').config();
const users = require('../api/user/user.router')
const keys = require('../api/keys/keys.router')
const equipmentType = require('../api/equipmenttypes/equipmenttype.router');
const auth = require('../api/authentication/auth.router')
const helmet = require('helmet')
const express = require('express')
module.exports = function (app) {
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'))
app.use(helmet.xssFilter())
app.use(helmet.frameguard())
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', process.env.ALLOWED_ORIGIN);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, x-auth-token, x-api-key');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
})
app.use('/api/user', users)
app.use('/api/auth', auth)
app.use('/api/key', keys)
app.use('/api/equipmenttypes', equipmentType)
}
Firstly, install cors by npm i cors
Add this to your server.js file:
const cors = require("cors");
app.use(cors());
The solution was simple, I changed the line inse my env file this:
ALLOWED_ORIGIN=*
No, this is not a good thing to do, and not secure at all, but now i can accsess the backend api from localhost, and i can optimize my work.
This question already has answers here:
How to resolve 'preflight is invalid (redirect)' or 'redirect is not allowed for a preflight request'
(6 answers)
Closed 2 years ago.
I have built a microservice backend deployed on kubernetes on Digital Ocean.
I am trying to connect my react code to the backend and getting the below error:
Access to XMLHttpRequest at 'http://cultor.dev/api/users/signin' from origin 'http://localhost:3000'
has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.
Index.ts settings:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', '*');
res.header('Access-Control-Request-Headers', '*');
if (req.method === "OPTIONS") {
res.header('Access-Control-Allow-Methods', '*');
return res.status(200).json({});
}
next();
});
I would really appreciate the help. Thanks!
Install the cors middleware with
npm install cors
And you can use it directly like this:
const cors = require('cors');
app.use(cors());
Or you can set specific options like this:
const cors = require('cors');
const corsOpts = {
origin: '*',
credentials: true,
methods: ['GET','POST','HEAD','PUT','PATCH','DELETE'],
allowedHeaders: ['Content-Type'],
exposedHeaders: ['Content-Type']
};
app.use(cors(corsOpts));
You can replace origin with your website and allowedHeaders with the headers you're going to use.
I suggest trying to use cors middleware instead of puting the headers by yourself. Maybe you're missing something. You can download cors middleware from npm and use it in your express app
const cors = require('cors')
app.use(cors())
This question already has answers here:
How to enable cors nodejs with express?
(10 answers)
Closed 3 years ago.
Im trying to get a text/html of an url differnt from origin, but i cant get a POST because a CORS block.
Im makeing the requisition in angular this way:
const express = require('express');
const cors = require('cors');
validateOperador(login,pass){
const url = `${this.operadoresValidateUrl}a=${login}&b=${pass}`
return this.http.get(url,{headers:
{'Content-Type': 'text/html', 'Access-Control-Allow-Origin': '*' } })
}
and my node backend using express, is configured this way:
app.use(function (req, res, next) {
//Enabling CORS
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, x-client-key, x-client-token, x-client-secret, Authorization");
next();
});
httpServer = http.createServer(app);
app.use(cors())
app.use(bodyParser.json())
app.use(compression());
Im getting this error:
Access to XMLHttpRequest at 'my api url' from origin 'my project url' 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.
This is not a duplicated question, because I´ve already installed and runned CORS
You must not add 'Access-Control-Allow-Origin': '*' from client side.
Also you are doing a GET and not a POST not sure if that's what you want.
Also it seems a duplicate of this
Install cors: npm install cors
const cors = require('cors');
Then use in your index.js
app.use(cors())
i've created a small API using Node/Express and trying to pull data using Angularjs but as my html page is running under apache on localhost:8888 and node API is listen on port 3000, i am getting the No 'Access-Control-Allow-Origin'. I tried using node-http-proxy and Vhosts Apache but not having much succes, please see full error and code below.
XMLHttpRequest cannot load localhost:3000. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:8888' is therefore not allowed access."
// Api Using Node/Express
var express = require('express');
var app = express();
var contractors = [
{
"id": "1",
"name": "Joe Blogg",
"Weeks": 3,
"Photo": "1.png"
}
];
app.use(express.bodyParser());
app.get('/', function(req, res) {
res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')
Angular code
angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {
$http.get('localhost:3000').then(function(response) {
var data = response.data;
$scope.contractors = data;
})
HTML
<body ng-app="contractorsApp">
<div ng-controller="ContractorsCtrl">
<ul>
<li ng-repeat="person in contractors">{{person.name}}</li>
</ul>
</div>
</body>
Try adding the following middleware to your NodeJS/Express app (I have added some comments for your convenience):
// Add headers before the routes are defined
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// 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();
});
(You might need to use 127.0.0.1 instead of localhost.)
Accepted answer is fine, in case you prefer something shorter, you may use a plugin called cors available for Express.js.
It's simple to use, for this particular case:
var cors = require('cors');
// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));
(You might need to use 127.0.0.1 instead of localhost.)
The request origin needs to match the allowed origin(s), and you can also have multiple of them:
app.use(
cors({origin: ['http://localhost:8888', 'http://127.0.0.1:8888']})
);
Another way, is simply add the headers to your route:
router.get('/', function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
res.setHeader('Access-Control-Allow-Credentials', true); // If needed
res.send('cors problem fixed:)');
});
The top answer worked fine for me, except that I needed to whitelist more than one domain.
Also, top answer suffers from the fact that OPTIONS request isn't handled by middleware and you don't get it automatically.
I store whitelisted domains as allowed_origins in Express configuration and put the correct domain according to origin header since Access-Control-Allow-Origin doesn't allow specifying more than one domain.
Here's what I ended up with:
var _ = require('underscore');
function allowCrossDomain(req, res, next) {
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
var origin = req.headers.origin;
if (_.contains(app.get('allowed_origins'), origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
if (req.method === 'OPTIONS') {
res.send(200);
} else {
next();
}
}
app.configure(function () {
app.use(express.logger());
app.use(express.bodyParser());
app.use(allowCrossDomain);
});
The answer code allow only to localhost:8888. This code can't be deployed to the production, or different server and port name.
To get it working for all sources, use this instead:
// 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();
});
Install cors dependency in your project:
npm i --save cors
Add to your server configuration file the following:
var cors = require('cors');
app.use(cors());
It works for me with 2.8.4 cors version.
Hi this happens when the front end and backend is running on different ports. The browser blocks the responses from the backend due to the absence on CORS headers. The solution is to make add the CORS headers in the backend request. The easiest way is to use cors npm package.
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
This will enable CORS headers in all your request. For more information you can refer to cors documentation
https://www.npmjs.com/package/cors
This worked for me.
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('hello world')
})
You can change * to fit your needs. Hope this can help.
All the other answers didn't work for me. (including cors package, or setting headers through middleware)
For socket.io 3^ this worked without any extra packages.
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
app.all('*', function(req, res,next) {
/**
* Response settings
* #type {Object}
*/
var responseSettings = {
"AccessControlAllowOrigin": req.headers.origin,
"AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name",
"AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
"AccessControlAllowCredentials": true
};
/**
* Headers
*/
res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
res.header("Access-Control-Allow-Origin", responseSettings.AccessControlAllowOrigin);
res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
});
Add following code in app.js of NODEJ Restful api to avoid "Access-Control-Allow-Origin" error in angular 6 or any other framework
var express = require('express');
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
//enables cors
app.use(cors({
'allowedHeaders': ['sessionId', 'Content-Type'],
'exposedHeaders': ['sessionId'],
'origin': '*',
'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
'preflightContinue': false
}));
You could use cors package to handle it.
var cors = require('cors')
var app = express()
app.use(cors())
for setting the specific origin
app.use(cors({origin: 'http://localhost:8080'}));
know more
You can use "$http.jsonp"
OR
Below is the work around for chrome for local testing
You need to open your chrome with following command. (Press window+R)
Chrome.exe --allow-file-access-from-files
Note : Your chrome must not be open. When you run this command chrome will open automatically.
If you are entering this command in command prompt then select your chrome installation directory then use this command.
Below script code for open chrome in MAC with "--allow-file-access-from-files"
set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
second options
You can just use open(1) to add the flags: open -a 'Google Chrome' --args --allow-file-access-from-files
/**
* Allow cross origin to access our /public directory from any site.
* Make sure this header option is defined before defining of static path to /public directory
*/
expressApp.use('/public',function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
// Request headers you wish to allow
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// Set to true if you need the website to include cookies in the requests sent
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
/**
* Server is about set up. Now track for css/js/images request from the
* browser directly. Send static resources from "./public" directory.
*/
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.
Apart from all listed answers, I had the same error
I have both access to frontend and backend, I already added cors module app.use(cors()); Still, I was struggling with this error.
After some debugging, I found the issue. When I upload a media which size was more than 1 MB then the error was thrown by Nginx server
<html>
<head>
<title>413 Request Entity Too Large</title>
</head>
<body>
<center>
<h1>413 Request Entity Too Large</h1>
</center>
<hr>
<center>nginx/1.18.0</center>
</body>
</html>
But in the console of frontend, I found the error
Access to XMLHttpRequest at 'https://api.yourbackend.com' from origin 'https://web.yourfromntend.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
So It makes confusion here. But the route cause of this error was from nginx configuration. It's just because the directive client_max_body_size value has been set to 0 by default. It determines what the allowable HTTP request size can be is client_max_body_size. This directive may already be defined in your nginx.conf file located at /etc/nginx/nginx.conf Now you need to add/edit the value of the directive client_max_body_size either at http or server.
server {
client_max_body_size 100M;
...
}
Once you have set your desired value, save your changes and reload Nginx: service nginx reload
After these changes, It's working well
REFERENCE: https://www.keycdn.com/support/413-request-entity-too-large#:~:text=%23,processed%20by%20the%20web%20server.&text=An%20example%20request%2C%20that%20may,e.g.%20a%20large%20media%20file).
We'll see if the top 2 answers accept my edit, but it's very likely you're gonna have to either add or use 127.0.0.1 instead of localhost.
With the cors package, you're even able to use more than one allowed origin:
app.use(
cors({ origin: ["http://localhost:8888", "http://127.0.0.1:8888"] })
);
And you could use origin: "*" if you wish to allow for anything.
For more info, do check out Web Dev Simplified's tutorial.