No 'Access-Control-Allow-Origin' header is present on the requested resource. - angularjs

I've seen several questions and answers around this and mine is half working.
I have a node.js api server with url api.domain.com and the website on an nginx server at www.domain.com when I do the following in angular the request goes through on the api server, I see the request I see it getting parsed and put into the database. However, on the client side I do not get a return right away and then eventually I will see No 'Access-Control-Allow-Origin' header is present on the requested resource.
I know what is causing this behavior but shouldn't it throw the error before it hits the API server? Also note that the node.js server has cors enabled. The response that should be coming back is json.
$http({
method: 'POST',
url: "http://api.domain.com/addtrans/" + $scope.accountID,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT',
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {
payload: JSON.stringify(trans)
}
}).success(function (result) {
$scope.trans = {};
console.log(result);
});

I have used the below middleware for all of our projects and it has been proven to work best.
const allowCors = (req, res, next) => {
/** Allow all origins, for now TODO */
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type');
res.header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
/** Browser check for pre-flight request to determine whether the server is webdav compatible */
if ('OPTIONS' == req.method) {
res.sendStatus(204);
}
else next();
};
// Put this code before the routes you want to allow CORS to
app.use(allowCors);
You should change the Allow-Origin to something more restricted for security reasons.
The above code covers CORS as well as pre-flight on most browsers(this ia major issue we were having in the beginning).

i used this a while ago (express 3.x):
// npm install --save cors
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
app.use(express.static());
app.get('*', function(){});
require('http').createServer(app).listen(3000)

Remember that the cors header should be on the response which is coming from server not the request which is sent from client.
You can use a middleware to enable cors on the server:
//CORS middleware
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);
...
});

Related

CORS error occurs when HTTPS applied to the my server using Let's Encrypt

I have a Digital Ocean Linux server.
I deployed my REST API and also front end in the same server.
My Back End runs using Node.JS and front end using AngularJS.
After enabling HTTPS, I changed all the REST URLs into HTTPS.
Like this :
var mainHost = "https://xxx.xxx.xxx.xx:7000/api";
Now I'm getting this CORS error :
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxx.xxx.xxx.xx:7000/api/user_manage/login. (Reason: CORS request did not succeed).
I am using Node.JS CORS plugin also.
var cors = require('cors');
var app = express();
app.use(cors());
This started when I added HTTPS and I tried many things. Including changing the .htaccess and adding some meta tags. Still no good. What is the reason for this ? Why CORS error comes after adding HTTPS ? Please help me to solve this.
This is the controller call for the service layer :
sessionService.getAllSessions(100, 0).then(function (data) {
console.log(data);
$scope.allSessions = data.data;
});
And this is the service layer :
getAllSessions: function (limit, offset) {
return $http({
method: "GET",
url: host.session_manage + '/session/' + limit + '/' + offset
}).then(function (response) {
return response.data;
});
}
I'm not using headers in the service call as you can see in the above section.
This is the server code snippet :
var express = require("express");
var bodyParser = require("body-parser");
var morgan = require("morgan");
var config = require("./config");
// var cors = require('cors');
var app = express();
// app.use(cors());
// app.use(cors({
// origin: 'https://xxxxxx.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(); });
app.set('views', './app/views');
app.set('view engine', 'pug');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan('dev'));
var session = require('./app/routes/session')(app, express);
app.use('/api/session_manage', session);
app.listen(config.port, function (err) {
if (err) {
console.log(err);
} else {
console.log("localhost:7000");
}
});
Thank you guys.
You are in production you don't want to allow CORS access for all origins but if you need to allow cross origin requests from some specified host(s) you can do add the following code:
server.use(cors({
origin: 'https://example.com'
}));
This will allow https://example.com to send cross origin requests to your Express server without the Same Origin Policy getting in the way.
You can also enable CORS for a single Express route
server.get('/endpoint', cors(), function (req, res, next) {
res.json({msg: 'This has CORS-enabled for only this route: /endpoint'})
})
If you want to allow multiple origins you need to use a function (for origin instead of a string) that dynamically set the CORS header depending on the origin making the request and a white list that you specify which contains the origin to allow.
var whitelist = ['http://example.com', 'http://othersite.com'];
var options = { origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
server.use(cors(options))

angularjs malforms json while sending data to the server using POST

I have a Nodejs express server and an angularJs client which sends data to the server.
The problem is when I try to send a JSON to the server with angularJS, the received JSON becomes like this:
{"{\"question\":\"What will be result of code int a ":" 5/2\",\"answers\":[{\"a\":\"2.50\",\"b\":\"1\",\"c\":\"2\",\"d\":\"no right answer\"}],\"answer\":\"c\",\"score\":\"100\"}"}
Here is my post method in angularJS:
createQuestion: function(question){
delete question["_id"];
console.log(JSON.stringify(question))
return $http.post('http://localhost:3000/questions/', question, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.then(
function(response){
return response.data;
},
function(errResponse){
console.error('Error while creating question');
return $q.reject(errResponse);
}
);
}
the output of console.log(JSON.stringify(question)) is:
{"question":"What will be result of code int a = 5/2","answers":[{"a":"2.50","b":"1","c":"2","d":"no right answer"}],"answer":"c","score":"100"}
Here is the part of the code in nodejs responsible for POST methods:
exports.create_a_question = function(req, res) {
console.log(JSON.stringify(req.body))
var new_question = new Question(req.body);
new_question.save(function(err, question) {
if (err)
res.send(err);
res.json(question);
});
};
After a search I found out that this problem happens because of application/x-www-form-urlencoded in the header of requests but I add this configuration to my nodejs server and the problem still persists:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
Here is CORS headers on nodejs server:
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Max-Ag', '3600');
How can I solve the problem?
The back slashes ("\") happen when JSON.stringify is called twice:
var x = {a:1, b:2};
var y1 = JSON.stringify(x);
var y2 = JSON.stringify(y1);
console.log(y2);
The AngularJS framework automatically does a JSON.stringify with the $http.post method. The second JSON.stringify was called in the Node.js code.
The solution is to use JSON.parse in the Node.js code:
var x = {a:1, b:2};
var y1 = JSON.stringify(x);
var y2 = JSON.parse(y1);
console.log(y2);
So here is how I solved the problem:
download the cors library via npm:
npm install --save cors
use it in the code:
var cors = require('cors');
app.use(cors());
then I removed the unnecessary header option when calling angularjs $http.post
Possibly:
headers: { 'Content-Type': 'multipart/form-data', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache'}
Since there are multiple content types at issue here ...

Cross- origin request

I want to Upload Image in backened from frontend....I'll use ngFileUploader bower Component.
My frontend code is:
function SampleController(SampleData,Upload,$http) {
var vm = this;
vm.uploadFiles = function(files, errFiles) {
Upload.upload({
url: "localhost:5000/upload", //webAPI exposed to upload the file
data: {
file: files
}
}).then(function(resp) {
console.log(resp)});
}
And i'll added ngf-select in its html file.
And it will show the error--
XMLHttpRequest cannot load localhost:5000/upload. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
How can I resolved it??
you need to add this:
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Origin: *');
My project backend is laravel. So, I included this in Route file.
Add cors filter to your application as a middleware
var app = require('express')();
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', 'PUT', 'POST', 'DELETE']);
next();
});
I would recommend you white list the origins you would allow.

Access-Control-Allow-Origin' header is present on the requested resource

I am trying to login using google authentication using node.js, but it showing error like below.
XMLHttpRequest cannot load https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_ur…d=410427634474-u3tpasmj4r80s6v20o54s85fikhotl79.apps.googleusercontent.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Someone please help me to solve this, because i am trying this from past two days, still didn't fix.
Try adding the following middleware to your NodeJS/Express app (I have added some comments for your convenience):
// 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();
});
Write this in app.get function.
res.set('Access-Control-Allow-Origin', '*');
You can use node function as
app.get("/png",function(req,res){
res.set('Access-Control-Allow-Origin', '*');
var sr = { data: "", message: "", error: "" };
console.log(222);
connection.query('SELECT * FROM png ', function(err, rows, fields) {
connection.end();
if (!err)
{
var userr = rows;
sr.data = userr;
res.json(sr);
} else{
console.log('Error while performing Query.');
}
});
});

Bluemix Cors disable Node.js

I am not able to avoid this error on my browser - XMLHttpRequest cannot load https://xyz.mybluemix.net/get_user_byId.Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.x.y.z:9000' is therefore not allowed access. The response had HTTP status code 404.
I am using every measure required to actually allow cross origin calls, but still it gives me an error.
var app = express();
var cors = require('cors');
app.use(cors());
app.use(function(request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
next();
});
app.get('/get_users', cors(), function(req, res) {...}
I am calling this api like - (standard $http angular way)
return $http.post(base+"get_user_byId", id)
You need only:
var cors = require('cors'); //Importing this middleware enables CORS
and
app.use(cors());
to allow CORS in express/connect applications
Delete these lines:
app.use(function(request, response, next) {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
next();
});
and set your GET API with:
app.get('/get_users', function(req, res) {...}
Reference - Enable all CORS: https://www.npmjs.com/package/cors#simple-usage-enable-all-cors-requests
In angularJS you have to call that API with GET method (no post) because you have defined /get_users api with get method.
I suggest you to use this snippet:
var par = {
id: myId,
};
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http({
method : "GET",
params: par,
url : base + "/get_users"
}).then(function mySucces(response) {
$scope.myData = response.data;
}, function myError(response) {
$scope.myData = response.statusText;
});
});

Resources