CORS Issue - Angular 8 - NodeJS & ExpressJS - javascript

I've tried a few different solutions from other threads and suspect I'm missing something small here.
I have an AngularJS 8 application, running on Node 10 with ExpressJS. Having some CORS issues when trying to access Google's People API.
Access to XMLHttpRequest at 'https://developers.google.com/people/api/rest/v1/people.connections' from origin 'http://app.x.com' 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
My frontend code looks like:
return this.httpClient.get(this.API_URL, {
headers: new HttpHeaders({
Authorization: `Bearer ${authtoken}`,
'Access-Control-Allow-Origin': 'http://localhost:4200',
'Access-Control-Allow-Credentials': 'true',
})
});
}
My server side code:
let express = require('express'),
path = require('path'),
cors = require('cors');
// Connecting mongoDB
var compression = require('compression')
var session = require("express-session");
let app = express();
app.use(session({
secret: '#######################',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
app.use(compression())
app.use(cors());
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 corsOptions = {
origin: '*',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions));
*/
app.use(express.static(path.join(__dirname, 'dist/###')));
app.use('/*', express.static(path.join(__dirname, 'dist/##')));
// Create port
const port = 8080;
const server = app.listen(port, () => {
console.log('Connected to port ' + port)
})
// Find 404 and hand over to error handler
app.use((req, res, next) => {
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();
});
app.use(function (err, req, res, next) {
console.error(err.message);
if (!err.statusCode) err.statusCode = 500;
{
res.status(err.statusCode).send(err.message);
}
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
if (!err.statusCode) err.statusCode = 500;
{
res.status(err.statusCode).send(err.message);
}
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();
});
As you can see, I've tried a couple of different approaches. Would appreciate any suggestions.
Thank You

Fixed the issue in another way. Using the Gapi library (javascript: https://github.com/google/google-api-javascript-client/blob/master/docs/reference.md ) and its Auth, I was able to login, get the JWT and use that as a credential.
const googleUser = await googleAuth.signIn();
const token = googleUser.getAuthResponse().id_token;
const credential = firebase.auth.GoogleAuthProvider.credential(token);
await firebase.auth().signInAndRetrieveDataWithCredential(credential);
return googleUser;
Using that credential login to firebase. All the while, being loggedin to Google Api's thanks to Gapi's Javascript Library. You can use a gapi instance then to request resources and api's depending on your scope of course.
const contacts = await gapi.client.request({
'path': 'https://people.googleapis.com/v1/people/me/connections?personFields=email_addresses,names&pageToken=CAAQwo2YuIUuGgYKAghkEAI&pageSize=2000',
})
No CORS issues, no fuss. Just posting incase it helps someone else save some time.

Related

XMLHttpRequest has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response

I am having issues creating new users from the form due to CORS. I was able to last week in this app but not sure what is missing from my server (methods, origin, headers, etc.)or my API call.
Here is what is suggested in the issues part of the console:
To fix this issue, include the additional request headers you want to use in the Access-Control-Allow-Headers response header of the associated preflight request.
1 request
Request Status Preflight Request Disallowed Request Header
new_user blocked
new_user content-type
Here is the server code:
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
// Cookies:
const cookieParser = require('cookie-parser');
require('./config/mongoose.config');
app.use(cookieParser());
//required for post request
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// routes:
require('./routes/user.routes')(app);
require('./routes/spot.routes')(app);
// blocking cors errors:
const corsOptions = {
origin: 'http://localhost:3000',
methods: ["GET", "POST"],
allowedHeaders: ["*"],
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus: 200,
}
app.use(cors(corsOptions)) // Use this after the variable declaration
// MIDDLEWARE:
// app.use(cors(
// { credentials: true, origin: 'http://localhost:3000' },
// { headers: { "Access-Control-Allow-Origin": "*" } }));
// Middleware CORS API CALLS:
app.use((req, res, next) => {
if (req.method === "OPTIONS") {
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET", true);
return res.status(200).json({});
}
next();
});
//listen on port:
app.listen(9000, () => {
console.log("Listening at Port 9000")
})
Here are the routes:
const UserController = require('../controllers/user.controllers');
const { authenticate } = require('../config/jwt.config');
module.exports = function (app) {
app.post('/api/new_user', authenticate, UserController.register);
app.get('/api/users', UserController.getAllUsers);
app.get('/api/users/:id', UserController.login);
app.post('/api/users/logout', UserController.logout);
app.put('/api/users/:id', UserController.updateUser);
app.delete('/api/users/:id', UserController.deleteUser);
}
Here is the client (form code):
const onSubmitHandler = e => {
e.preventDefault();
const { data } =
axios.post('http://localhost:9000/api/new_user', {
userName,
imgUrl,
email,
password,
confirmPassword
},
{ withCredentials: true, },
// { headers: { 'Access-Control-Allow-Origin': '*' } }
{ headers: ["*"] }
)
.then(res => {
history.push("/dashboard")
console.log(res)
console.log(data)
})
.catch(err => console.log(err))
I've done a bit of research and not sure if I should make a proxy, use a plugin, etc, but I could use the extra eyes. Thanks all!
If you're already using the cors middleware, you don't need to manually handle OPTIONS requests, it does that for you.
Remove this section...
// Middleware CORS API CALLS:
app.use((req, res, next) => {
if (req.method === "OPTIONS") {
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET", true);
return res.status(200).json({});
}
next();
});
You should also register the cors middleware before your routes, along with your other middleware.
app.use(cors({
origin: "http://localhost:3000",
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus: 200,
}))
//required for post request
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// routes:
require('./routes/user.routes')(app);
require('./routes/spot.routes')(app);
On the client-side, ["*"] is an invalid request header and needs to be removed. You're also not handling the async response correctly. It should be
axios.post("http://localhost:9000/api/new_user", {
userName,
imgUrl,
email,
password,
confirmPassword
}, { withCredentials: true, }).then(res => {
history.push("/dashboard")
console.log(res)
console.log(res.data) // 👈 this is where `data` is defined
}).catch(console.error)
I think that it is caused by this line return res.status(200).json({});
When you respond to the CORS pre-flight you are not supposed to include a Content-Type and setting the return type to JSON probably does exactly this.
Try
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET", true);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return res.status(200).end();

How to make a GET call to api.github with Express server

I'm blocked since 3 days and did my research on the internet. Here' is the code.
api.js
const express = require('express');
const router = express.Router();
var http = require('http');
var https = require("https");
router.get('/github', async function (req, res) {
https.get('https://api.github.com/v3/users/tmtanzeel', function (apiRes) {
apiRes.pipe(res);
}).on('error', (e) => {
console.error(e);
res.status(500).send('Something went wrong');
});
});
Output:
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes.
I found something useful here:
In Node.js/Express, how do I automatically add this header to every "render" response?
Requesting https://api.github.com/users (api) returns System.Net.HttpStatusCode.Forbidden IsSuccessStatusCode = false
But these were not very helpful.
I tried: res.setHeader("User-Agent", "My App"); but I'm not very sure about the second argument.
Modified server.js
const express = require('express');
const app = express();
const api = require('./routes/api');
const cors = require('cors');
app.use(cors());
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);
res.setHeader("User-Agent", "My App"); // <-------------ADDED HEADER HERE
// Pass to next layer of middleware
next();
});
app.use('/api', api);
app.get('/', function (req, res) {
res.send('Server is up and running!');
})
app.listen(3000, function () {
console.log('Server listening on 3000 port');
});
Have you ever face this kind of issue. Please help.
You are setting headers to your response. Instead, you must set headers in the API call you make. You can pass options object to the http.get() method and set headers there.
router.get('/github', async function (req, res) {
const options = {
hostname: 'api.github.com',
path: '/v3/users/tmtanzeel',
headers: {
'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1521.3 Safari/537.36'
}
}
https.get(options, function (apiRes) {
apiRes.pipe(res);
}).on('error', (e) => {
console.error(e);
res.status(500).send('Something went wrong');
});
});
See this answer on setting github user-agent header:
https://stackoverflow.com/a/16954033/4185234

No 'Access-Control-Allow-Origin' header is present on the requested resource with Vuejs and Nodejs

Backend (nodejs)
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, Authorization, Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next(createError(404));
});
Frontend vuejs
axios.post(`http://localhost:5000/api/v1/users/uploadDocuments?access_token=`+store.state.token,
{
data: formData,
//accessToken: store.state.token
},
{ headers: {
'Content-Type': 'Application/json',
// 'x-access-token': localStorage.getItem('token')
}
}
).then (function (response) {
this.potato = response.data
})
I am getting the following error:
Failed to load http://localhost:5000/api/v1/users/uploadDocuments?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.et: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
I have added Access-Control-Allow-Origin in the backend but the error still persists. How can I fix this ?
Try this instead of what you have now
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin,X-Requested-With,Content-Type,Accept,Authorization"
);
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET')
return res.status(200).json({});
}
next();
});
Install CORS
npm install cors
Now, include it into app()
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())

Can't allow Cross-Origin Request in local Nodejs server

I've created a local REST API server in nodejs, which is fetching data from local Mongodb database. I've also created a basic web page, which request this data from the server locally. Now, when I try to get data from web page, it gives me following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4000/todos. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
I've searched about on stackoverflow, and found THIS and THIS solutions. I've added the suggested headers in my main app.js file. But still it gives the same error.
Following is my servers app.js file, where I've added these headers.
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var todos = require('./routes/todos');
// load mongoose package
var mongoose = require('mongoose');
// Use native Node promises
mongoose.Promise = global.Promise;
// connect to MongoDB
mongoose.connect('mongodb://localhost/todo-api')
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/todos', todos);
// 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();
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
And following is the code(Angularjs) of web page, from where I want to get data from my API.
dbConnection.html
<html ng-app="demo">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"> </script>
<head>
<title> dbConnection Demo</title>
</head>
<body ng-controller="db">
<div ng-repeat="product in db.products">
{{product._id}} </br>
</div>
</body>
<script>
var app = angular.module('demo', []);
app.controller('db', ['$http', function($http){
var store = this;
store.products = [];
$http({
method: 'GET',
url: 'http://localhost:4000/todos'
}).then(function (success){
store.products = success;
},function (error){
});
}]);
</script>
</html>
Even after I've added headers as suggested in the answers, I'm getting the same error. What am I missing here? I'm completely newbie in this field. Thanks!
Does your request require a pre-flight response? If it does, it will be trying to hit your endpoint with method 'OPTIONS' and unless you have set one up, you will see the cors issue.
So if you find that the preflight response is failing, you can either add a custom options route, or potential use the npm cors package - https://www.npmjs.com/package/cors
npm install cors --save
In your app.js
var cors = require('cors')
app.options('*', cors()) // include before other routes
app.use(cors())
I finally figured out the solution by adding those headers in my routes as following:
routes/todos.js
...
...
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,contenttype'); // If needed
res.setHeader('Access-Control-Allow-Credentials', true); // If needed
res.send('cors problem fixed:)');
});
Please move the header code after var app = express();
That mean you must place them before define router.
var app = express();
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();
});
// Router
You might have to add:
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Why? Well I think I had the same problem and this solved it for me.
use cors dependency.
first install cors by
npm i cors
then import and use like this:
const cors = require("cors");
app.use(express.json());
app.use(cors());
and it will work.

Getting No 'Access-Control-Allow-Origin' header is present on the requested resource issue using node with localhost [duplicate]

I am trying to support CORS in my Node.js application that uses the Express.js web framework. I have read a Google group discussion about how to handle this, and read a few articles about how CORS works. First, I did this (code is written in CoffeeScript syntax):
app.options "*", (req, res) ->
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
# try: 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
# try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
It doesn't seem to work. It seems like my browser (Chrome) is not sending the initial OPTIONS request. When I just updated the block for the resource I need to submit a cross-origin GET request to:
app.get "/somethingelse", (req, res) ->
# ...
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
It works (in Chrome). This also works in Safari.
I have read that...
In a browser implementing CORS, each cross-origin GET or POST request is preceded by an OPTIONS request that checks whether the GET or POST is OK.
So my main question is, how come this doesn't seem to happen in my case? Why isn't my app.options block called? Why do I need to set the headers in my main app.get block?
I found the easiest way is to use the node.js package cors. The simplest usage is:
var cors = require('cors')
var app = express()
app.use(cors())
There are, of course many ways to configure the behaviour to your needs; the page linked above shows a number of examples.
Try passing control to the next matching route. If Express is matching app.get route first, then it won't continue onto the options route unless you do this (note use of next):
app.get('somethingelse', (req, res, next) => {
//..set headers etc.
next();
});
In terms of organising the CORS stuff, I put it in a middleware which is working well for me:
// CORS middleware
const allowCrossDomain = (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(() => {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: `cool beans` }));
app.use(express.methodOverride());
// CORS middleware
app.use(allowCrossDomain);
app.use(app.router);
app.use(express.static(`public`));
});
To answer your main question, the CORS spec only requires the OPTIONS call to precede the POST or GET if the POST or GET has any non-simple content or headers in it.
Content-Types that require a CORS pre-flight request (the OPTIONS call) are any Content-Type except the following:
application/x-www-form-urlencoded
multipart/form-data
text/plain
Any other Content-Types apart from those listed above will trigger a pre-flight request.
As for Headers, any Request Headers apart from the following will trigger a pre-flight request:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Save-Data
Viewport-Width
Width
Any other Request Headers will trigger the pre-flight request.
So, you could add a custom header such as: x-Trigger: CORS, and that should trigger the pre-flight request and hit the OPTIONS block.
See MDN Web API Reference - CORS Preflighted requests
To stay in the same idea of routing. I use this code :
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
Similar to http://enable-cors.org/server_expressjs.html example
do
npm install cors --save
and just add these lines in your main file where your request going (keep it before any route).
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
I have made a more complete middleware suitable for express or connect. It supports OPTIONS requests for preflight checking. Note that it will allow CORS access to anything, you might want to put in some checks if you want to limit access.
app.use(function(req, res, next) {
var oneof = false;
if(req.headers.origin) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
oneof = true;
}
if(req.headers['access-control-request-method']) {
res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
oneof = true;
}
if(req.headers['access-control-request-headers']) {
res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
oneof = true;
}
if(oneof) {
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
}
// intercept OPTIONS method
if (oneof && req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
});
Do something like this:
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();
});
install cors module of expressjs. you can follow these steps >
Installation
npm install cors
Simple Usage (Enable All CORS Requests)
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
for more details go to https://github.com/expressjs/cors
Testing done with express + node + ionic running in differente ports.
Localhost:8100
Localhost:5000
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
first simply install cors in your project.
Take terminal(command prompt) and cd to your project directory and run the below command:
npm install cors --save
Then take the server.js file and change the code to add the following in it:
var cors = require('cors');
var app = express();
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();
});
This worked for me..
Some time ago, I faced this problem so I did this to allow CORS in my nodejs app:
First you need to install cors by using below command :
npm install cors --save
Now add the following code to your app starting file like ( app.js or server.js)
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
}));
require('./router/index')(app);
This works for me, as its an easy implementation inside the routes, im using meanjs and its working fine, safari, chrome, etc.
app.route('/footer-contact-form').post(emailer.sendFooterMail).options(function(req,res,next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
return res.send(200);
});
If you want to make it controller specific, you can use:
res.setHeader("X-Frame-Options", "ALLOWALL");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Please note that this will also allow iframes.
In my index.js I added:
app.use((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", "GET, POST, PUT, DELETE, OPTIONS");
next();
})
cors package is recommended way to for solving the CORS policy issue in express.js, but you also need to make sure to enable it for app.options as well, like below:
const cors = require('cors');
// enable cors
app.use(
cors({
origin: true,
optionsSuccessStatus: 200,
credentials: true,
})
);
app.options(
'*',
cors({
origin: true,
optionsSuccessStatus: 200,
credentials: true,
})
);
Can refer the code below for the same. Source: Academind/node-restful-api
const express = require('express');
const app = express();
//acts as a middleware
//to handle CORS Errors
app.use((req, res, next) => { //doesn't send response just adjusts it
res.header("Access-Control-Allow-Origin", "*") //* to give access to any origin
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization" //to give access to all the headers provided
);
if(req.method === 'OPTIONS'){
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); //to give access to all the methods provided
return res.status(200).json({});
}
next(); //so that other routes can take over
})
The easiest answer is to just use the cors package.
const cors = require('cors');
const app = require('express')();
app.use(cors());
That will enable CORS across the board. If you want to learn how to enable CORS without outside modules, all you really need is some Express middleware that sets the 'Access-Control-Allow-Origin' header. That's the minimum you need to allow cross-request domains from a browser to your server.
app.options('*', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send('ok');
});
app.use((req, res) => {
res.set('Access-Control-Allow-Origin', '*');
});
My simplest solution with Express 4.2.0 (EDIT: Doesn't seem to work in 4.3.0) was:
function supportCrossOriginScript(req, res, next) {
res.status(200);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type");
// res.header("Access-Control-Allow-Headers", "Origin");
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// res.header("Access-Control-Allow-Methods","POST, OPTIONS");
// res.header("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE, PUT, HEAD");
// res.header("Access-Control-Max-Age","1728000");
next();
}
// Support CORS
app.options('/result', supportCrossOriginScript);
app.post('/result', supportCrossOriginScript, function(req, res) {
res.send('received');
// do stuff with req
});
I suppose doing app.all('/result', ...) would work too...
Below worked for me, hope it helps someone!
const express = require('express');
const cors = require('cors');
let app = express();
app.use(cors({ origin: true }));
Got reference from https://expressjs.com/en/resources/middleware/cors.html#configuring-cors
Try this in your main js file:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
);
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
res.header("Allow", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
This should solve your problem
using CORS package. and put this parameters:
cors({credentials: true, origin: true, exposedHeaders: '*'})
In typescript, if you want to use the node.js package cors
/**
* app.ts
* If you use the cors library
*/
import * as express from "express";
[...]
import * as cors from 'cors';
class App {
public express: express.Application;
constructor() {
this.express = express();
[..]
this.handleCORSErrors();
}
private handleCORSErrors(): any {
const corsOptions: cors.CorsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
};
this.express.use(cors(corsOptions));
}
}
export default new App().express;
If you don't want to use third part libraries for cors error handling, you need to change the handleCORSErrors() method.
/**
* app.ts
* If you do not use the cors library
*/
import * as express from "express";
[...]
class App {
public express: express.Application;
constructor() {
this.express = express();
[..]
this.handleCORSErrors();
}
private handleCORSErrors(): any {
this.express.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-ALlow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
if (req.method === "OPTIONS") {
res.header(
"Access-Control-Allow-Methods",
"PUT, POST, PATCH, GET, DELETE"
);
return res.status(200).json({});
}
next(); // send the request to the next middleware
});
}
}
export default new App().express;
For using the app.ts file
/**
* server.ts
*/
import * as http from "http";
import app from "./app";
const server: http.Server = http.createServer(app);
const PORT: any = process.env.PORT || 3000;
server.listen(PORT);
Using Express Middleware works great for me. If you are already using Express, just add the following middleware rules. It should start working.
app.all("/api/*", function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
return next();
});
app.all("/api/*", function(req, res, next) {
if (req.method.toLowerCase() !== "options") {
return next();
}
return res.send(204);
});
Reference
If you want to get CORS working without the cors NPM package (for the pure joy of learning!), you can definitely handle OPTIONS calls yourself. Here's what worked for me:
app.options('*', (req, res) => {
res.writeHead(200, '', {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS',
}).end();
});
Nice and simple, right? Notice the use of res.writeHead() instead of res.header(), which I am unfamiliar with.
I found it to be extremely easy to do this with the npm request package (https://www.npmjs.com/package/request)
Then I based my solution on this post http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/
'use strict'
const express = require('express');
const request = require('request');
let proxyConfig = {
url : {
base: 'http://servertoreach.com?id=',
}
}
/* setting up and configuring node express server for the application */
let server = express();
server.set('port', 3000);
/* methods forwarded to the servertoreach proxy */
server.use('/somethingElse', function(req, res)
{
let url = proxyConfig.url.base + req.query.id;
req.pipe(request(url)).pipe(res);
});
/* start the server */
server.listen(server.get('port'), function() {
console.log('express server with a proxy listening on port ' + server.get('port'));
});
This is similiar to Pat's answer with the difference that I finish with res.sendStatus(200); instead of next();
The code will catch all the requests of the method type OPTIONS and send back access-control-headers.
app.options('/*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.sendStatus(200);
});
The code accepts CORS from all origins as requested in the question. However, it would be better to replace the * with a specific origin i.e. http://localhost:8080 to prevent misuse.
Since we use the app.options-method instead of the app.use-method we don't need to make this check:
req.method === 'OPTIONS'
which we can see in some of the other answers.
I found the answer here: http://johnzhang.io/options-request-in-express.
The simplest approach is install the cors module in your project using:
npm i --save cors
Then in your server file import it using the following:
import cors from 'cors';
Then simply use it as a middleware like this:
app.use(cors());
Hope this helps!
simple is hard:
let my_data = []
const promise = new Promise(async function (resolve, reject) {
axios.post('https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api/directions/json?origin=33.69057660000001,72.9782724&destination=33.691478,%2072.978594&key=AIzaSyApzbs5QDJOnEObdSBN_Cmln5ZWxx323vA'
, { 'Origin': 'https://localhost:3000' })
.then(function (response) {
console.log(`axios response ${response.data}`)
const my_data = response.data
resolve(my_data)
})
.catch(function (error) {
console.log(error)
alert('connection error')
})
})
promise.then(data => {
console.log(JSON.stringify(data))
})
If your Express Server has Authorization enabled, you can achieve that like this
const express = require('express');
const app=express();
const cors=require("cors");
app.use(cors({
credentials: true, // for authorization
}));
...
We can avoid CORS and forward the requests to the other server instead:
// config:
var public_folder = __dirname + '/public'
var apiServerHost = 'http://other.server'
// code:
console.log("starting server...");
var express = require('express');
var app = express();
var request = require('request');
// serve static files
app.use(express.static(public_folder));
// if not found, serve from another server
app.use(function(req, res) {
var url = apiServerHost + req.url;
req.pipe(request(url)).pipe(res);
});
app.listen(80, function(){
console.log("server ready");
});

Categories

Resources