I have a REST API deployed on localhost with the following GET endpoint: localhost:9000/get-events/1
This endpoint is returning the correct response when I send the request through Postman or through a web browser. It also contains CORS headers etc, and I have also handled the options requests with appropriate headers. (The server is implemented in Play Framework).
The response from Postman for the above GET request is:
headers:
Access-Control-Allow-Origin →*
Content-Length →34
Content-Security-Policy →default-src 'self'
Content-Type →application/json
Date →Tue, 10 Apr 2018 04:50:16 GMT
Referrer-Policy →origin-when-cross-origin, strict-origin-when-cross-origin
X-Content-Type-Options →nosniff
X-Frame-Options →DENY
X-Permitted-Cross-Domain-Policies →master-only
X-XSS-Protection →1; mode=block
body:
{
"status": "success",
"events": "[<some list....>]"
}
I basically want the list that is being returned by the server to be loaded in a ng-repeat list in my Event List page when the user is navigating to it. I have implemented this in my code like this:
inside the controller in app.js:
$scope.getlist = function() {
$http({
url: 'localhost:9000/get-events/1',
method: 'GET'
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.events = JSON.parse(response.data.events);
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
and in the front end, index.html:
Fetch List
and, eventList.html:
<ul>
<li data-ng-repeat="event in events">{{event.name}}</li>
</ul>
When I click on the link, it gives the following error in the browser's console:
ERROR: {"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"localhost:9000/get-events/1","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}
from the server logs, it seems that the request is not reaching the server at all.
The strange thing is that I am also sending a POST request to the same server, while doing the user login and that request is successfully reaching the server and correctly giving the response from the angularJS app.
This is how I call the POST from my angularjs controller:
$scope.login = function () {
console.log('login called');
var loginURL = '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 successLogin(response) {
console.log('SUCCESS: ' + JSON.stringify(response));
}, function failLogin(response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
What am I missing while doing the GET request?
In the server have you added CORS header Access-Control-Allow-Origin in server end ?
Its Working for me
try this.
html:
<a ng-click="getlist()">Fetch List</a>
js:
$scope.getlist = function () {
$http({
url: 'ControllerName/getevents/1',
method: 'GET'
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
output in console:
SUCCESS: {"data":"","status":200,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"Employee/getevents/1","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"OK","xhrStatus":"complete"}
So, I was running my Angular App using Firefox earlier and I just thought of using Google Chrome. It helped me by providing this extra information in the console:
Failed to load localhost:9000/volunteer-events/1: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
So, it seems that in the HTTP get URL I was just using localhost:9000... instead of the complete http://localhost:9000...
changing my URL to http://localhost:9000... fixed the problem.
Answering this here so that anyone else who was stuck on this for long time like me would benefit from it!
Although I am still not sure how it worked for the POST ?
Related
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));
});
}
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
I have one api which is being called from Angularjs from front end, when API hit from post-man it is taking hardly 1 sec to send response, but when it is being called from chrome browser, it leads to hangs it up and Aw, Snap! page.
we are using remote desktop, upon which only chrome is running with a single tab.
Any thoughts we this is happing to us, since api is fine with postman returning a response within 1 sec.
Sample Code of Angular service method, which send the response to controller,
this.getData() = function(chartJson) {
return $http({
method: "POST",
url: "api/xxxxxxxx/xxxxxxxx",
headers: { 'Content-Type': "Application/json" },
data: chartJson
});
};
In controller, we access this above method like,
this.getData()
.then(function(response){
console.log(response);
}, function(error){
console.log('Error '+error);
});
Thanks in advance.
I have Restfull API (localhost:8180) which is having secure authentication. Using Angular JS http (or other services) I need to login into that server and get my data from localhost:8180/api/version/?1 (this is just example) Please find my code below.
//configure file
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
//setting cookie
app.run(['$http', '$cookies', function($http, $cookies) {
$http.defaults.headers.post['JSESSIONID'] = $cookies.JSESSIONID;
}]);
// My Controller
$http({
url:'http://localhost:8180',
method:'POST',
data: {
username:'adminadmin',
password:'passpass'
},
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Credentials": true,
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Accept": "*/*",
'Authorization': 'Basic adminadmin:passpass' // I guess its wrong
}
})
.success (function(){
console.log("Success");
//Need to call my API here
})
.error(function(data, status, headers, config){
console.log("Failed");
});
Here I'm getting No Access-Control-Allow-Origin and Origin null
error. If success I need to call localhost:8180/api/version?1 inside
of the success method using get or post. Here my server is
localhost:9596. I need to call 8180 host from 9596 host and get the
data into 9596 host.
Whenever you are getting Cross-origin Error, you need to as the server guys to add some headers sent while sending responses back to the ajax request.
Basing on Backend you need to use different approach to making this change in server:
In Java Tomcat Server: You need to configure filter mapping
Source : http://enable-cors.org/server.html
Help, I've got 400 error on POST and or PUT method, but GET works just fine,
I'm using angular as front end and laravel as API, my server is using nginx,
I've used CORS and I everything works fine on my local vagrant which is running on apache.
I'm sure I have my route set correctly, here's some of it from the module I use:
Route::group(array('prefix'=>'/api', 'middleware' => 'cors'),function(){
Route::post('/create_level', 'LevelController#store');
Route::get('/read_level', 'LevelController#index');
Route::get('/read_level/{id}', 'LevelController#show');
Route::put('/read_level/{id}', 'LevelController#update');
Route::delete('/read_level/{id}', 'LevelController#destroy');
here's part of my angular service:
app.service("edulevelService", function ($http, $q, $rootScope)
{
edu.updateEdulevel = function(id, edu){
var deferred = $q.defer();
$http.put($rootScope.endPoint + 'read_level/'+ id, edu)
.success(function(res)
{
deferred.resolve(res);
})
.error(function(err, stat){
deferred.reject(err);
console.log('error code: Ser-UEDU');
});
return deferred.promise;
}
edu.createEdulevel = function(edu){
var deferred = $q.defer();
$http.post($rootScope.endPoint + 'create_level', edu)
.success(function(res)
{
deferred.resolve(res);
})
.error(function(err, stat){
deferred.reject(err);
console.log('error code: Ser-CEDU');
});
return deferred.promise;
}
....
oh I forgot to mention different method cause different error code POST cause 405, PUT cause 400, and I've tried using Postman:
POST is working using text type and return 405 using application/json,
but when I tried
PUT method even though it return 200 I only got NULL data entered to my db (text type), and if I use application/json it return 400
Please Help
Finally found solution:
change $http.post to:
$http({
method: "post",
url: $rootScope.endPoint + 'create_level',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $.param({ .... })
})
somehow it works, exept on my login page which using stellizer to do post method and i can't find how should I change it without breaking all the function...
any one?
I only need to add:
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
and
data: $.param({ ...... })