Cross Origin Request when Access-Control-Allow-Origin missing - angularjs

I am calling the url from server side language using nodejs. When i use that url on the client side, I am getting the CORS error. If I use POSTMAN then i am getting the reponse. I have searched through various forums and questions on Stack Overflow and I can't seem to find any solution to this. It would be appreciated if someone could provide some insight.
app.controller('Ctrl',['$scope','$http', function($scope,$http) {
var config = {
headers: {'Access-Control-Allow-Origin': 'https://developer.mozilla.org'}
}
$http({
url: 'http://localhost:8000/psp/getbank',
method: 'GET',
})
.then(
function successCallback(response) {
$scope.cspinfo = response.data;
console.log('Data Displayed successfully')
},
function errorCallback(response) {
console.log("Error:" + response.data)
})
}]);

The 'Access-Control-Allow-Origin' header is sent FROM the server, to let the client know where requests can come from. This is not a header you send TO the server.
This article specifies (among other things) the headers you are allowed to send in a CORS request: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Related

CORS error while sending request from Browser to play server even after sending CORS header

I have a REST API developed using Play Framework/Java and front end developed in Angular JS.
I am trying to call a POST method fron the Angular Client to the server using the following code:
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
$http({
url: loginURL,
method: 'POST',
data: loginInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
This is the code at my server:
public Result doLogin() {
ObjectNode result = Json.newObject();
result.put("status", "success");
return ok(result).withHeader("Access-Control-Allow-Origin", "*");
}
And this is the application conf file:
#allow all hosts.
play.filter.hosts {
allowed = ["."]
}
#allow CORS requests.
play.filters.cors {
allowedOrigins = ["*"]
}
Yet even after enabling CORS, I am getting error in console in both Firefox and Google Chrome:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:9000/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
ERROR: {"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:9000/login","data":{"email":"xxx","password":"xxx"},"headers":{"Content-Type":"application/json","Accept":"application/json, text/plain, /"}},"statusText":""}
I do know that the server is sending the correct response and the correct header because when I do the POST from Postman, I can see the response and also the headers containing {"Access-Control-Allow-Origin", "*"} in Postman.
So then, what could be the problem? Is there something I am missing from the Client side?
The difference between POSTMAN request and browser request is browser sends an OPTIONS request before the actual POST / GET request.
To be able to accept OPTION request with your play framework allowedHttpMethods = ["GET", "POST" ,"OPTIONS"]
for follow this link
Play Framework 2.3 - CORS Headers
This causes a problem accessing CORS request from a framework (like angularjs). It becomes difficult or the framework to find what was the options request for and take action properly.
For fixing your problem you will need to analyze how the options request going and how it's being interpreted and how to overcome. But in general, I suggest using "fetch" built-in request for this, which supports the promises so can be chained easily with angularjs code
so your code will look something like this
$scope.login = function () {
console.log('login called');
var loginURL = 'http://localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
fetch(loginURL, {
method: 'post',
headers: {
"Content-type": "application/json"
},
body: loginInfo
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.greeting = response.status;
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}

405 method not allowed using $http service AngularJS

I'm getting a 405 error making a request from localhost, this is the full error:
OPTIONS http://www.myurl.com 405 (Method Not Allowed)
XMLHttpRequest cannot load http://www.myurl.com. Response for preflight has invalid HTTP status code 405
I understand the problem but the quirk is that I get this error just when I use the angular $http service:
var req = {
method: 'POST',
url: 'http://www.myurl.com',
headers: {
'Content-Type': 'application/json'
},
data: {
}
}
$http(req)
.then(function(res) {},
function(error) {});
Using XMLHttpRequest works perfectly:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(xhttp.responseText);
}
};
xhttp.open("POST", 'http://www.myurl.com', true);
xhttp.send();
I have a chrome extension to add CORS headers and it is working. I also notice that if I remove the third parameter in xhttp.open the error appears again.
¿Does anyone know the reason? ¿How can I use the angular services without get the error?
You can write like this. Because you are not sending any parameter to the url. So I think this is a good way to do this. just try it may work for you.
$http.post('http://www.myurl.com').
success(function(data) {
//success Response here
});
You need to allow OPTIONS method on your server side. Before every GET, POST, PUT, DELETE... requests an OPTIONS request is launched.
I advise you to disable your "chrome extension to add CORS", to have the same configuration of your final users.

Request Forbidden 403 when request made to Square-Connect from localhost

I am trying to make a request to 'https://connect.squareup.com/v2/locations' using angularjs, where call is getting failed saying 403 FORBIDDEN.
Here is the code sample :
var url = 'https://connect.squareup.com/v2/locations';
var config = {
headers: {
'Authorization': 'Bearer sandbox-sq0atb-JJGltCa375qzAyoQbjPgmg',
'Accept': 'application/json',
"X-Testing": "testing"
}
};
$http.get(url, config)
.then(
function (response) {
console.dir(response);
},
function (response) {
console.log("failed" + response)
}
);
I have made a fiddle of the above sample. Any help is appreciated.
http://jsfiddle.net/dx6tdrha/
Are you seeing this error: XMLHttpRequest cannot load https://connect.squareup.com/v2/locations. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.? It means that you cannot access the API via front-end Javascript (like AngularJS) You'll need to use a different implementation like Node.js, PHP, etc.

I can't upload my files using angularjs?

$scope.uploadFiles = function () {
//debugger;
var request = {
method: 'POST',
url: 'http://localhost/upload/',
data: formdata,
headers: {
'Content-Type': undefined
}
};
// SEND THE FILES.
$http(request)
.success(function (d) {
alert(d);
})
.error(function () {
});
}
i am getting in console window like
XMLHttpRequest cannot load http://localhost/upload/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:55555' is therefore not allowed access. The response had HTTP status code 405.
If I understand this correctly, the app is running at http://localhost:55555 and you are trying to send a POST request to http://localhost/upload/ (which really means http://localhost:80/upload/). Your browser is not allowing you to do this since http://localhost:80/ and http://localhost:55555/ are different origins.
Perhaps you meant to say http://localhost:55555/upload/? This would solve your issue.
Otherwise you need to disable CORS in your browser or add the 'Access-Control-Allow-Origin: * header in your server at http://localhost:80/.

AngularJS POST fails with No 'Access-Control-Allow-Origin' when using data payload object but works using query params like payload

I am facing a weird issue. I am running my angularjs app in nodejs server locally which calls a POST API from my app located on Google App Engine. The API is configured with all CORS headers required as follows:
def post(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers.add_header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
self.response.headers.add_header("Access-Control-Allow-Headers", "X-Requested-With, content-type, accept, myapp-domain")
self.response.headers["Content-Type"] = “application/json; charset=utf-8”
GET requests to the API work without issues.
POST requests to the API work but ONLY when I send the post data as a 'string of params' and NOT when post data is sent as an object which is the right way to do. Eventually I need to be able to upload pictures using this API so the first solution below might not work for me. Please help!
METHOD 1: This works:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = "conversationid=1c34b4f2&userid=67e80bf6&content='Hello champs! - Web App'";
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz",
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
METHOD 2: This fails:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = ({
'conversationid' : '1c34b4f2',
'userid' : '67e80bf6',
'content' : 'Hello champs! - Web App'
});
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz"
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
When I use METHOD 2 it fails with the following error in the console:
XMLHttpRequest cannot load https://myapp-qa.appspot.com/message.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://0.0.0.0:8000' is therefore not allowed access.
Please let me know if you have any solution. Thanks in advance.
The issue is most likely with Angular sending a pre-flight OPTIONS request to check the access headers from the server. I am not sure how OPTIONS requests are handled in your API, but I am betting these headers are not being added. I suggest installing Fiddler to monitor the actual requests to see what is going on with the headers. You may only be adding them to your POST responses.
See this answer for details on why METHOD 1 may work in this scenario, while METHOD 2 does not.
Here are some more details about pre-flight requests.

Resources