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
Related
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 ?
While making a Ajax Request with Json object to "Web Api" using Angular js $http service.It raise CORS Issue,There is no Resolution by adding the following header "Access-Control-Allow-Origin" also,Please suggest me the right solution
Example:
var testmodule = angular.module('testmod', []);
testmodule.controller('testcontroller', function ($scope, $http)
{
$scope.Member ={'name':'andrew','age':12,'class':10}
$scope.savedata =function(){
$http({
url: "**api url**",
method: 'POST',
data: $scope.Member
}).success(function (data, status) { }).error(function (data, status, headers) { })
}
})
The "Access-Control-Allow-Origin" is a server side issue, you don't need to add any header in angularjs. add the following code to your server side:
("Access-Control-Allow-Origin", "*");
("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia");
you can refer to How to enable CORS in AngularJs
What is type of data angular sending? I use laravel + angular. I`m trying, but this script return 405 error. Method not allowed.
.controller('adminCtrl', function( $scope, $http ){
$scope.collection = [];
$scope.newData = [];
$scope.newrecord = function() {
$scope.collection.push($scope.newData);
$http({
url: '/newrecord',
method: "POST",
data: $.param($scope.collection),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data){
console.log(data);
})
}
})
You are getting 405 - Method not Allowed because the server you are sending your request does not have POST it the white list of methods allowed to be used to perform requests to that given API.
It's not an angularJS issue, it's a server configuration issue.
$http sends data as json.
You do not need to serialize params using "$.param", data is plain javascript object, which is send to your REST endpoint.
So attach just "$scope.collection) and do not set Content Type manually, it is json by default.
POST can be send also with convenience method.
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Here is the call I make the Parse.com's API to login the user:
var deferred = $q.defer();
$http({
method: "GET",
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json"
},
data: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data) {
deferred.resolve(data);
}).error(function() {
deferred.reject("error")
});
return deferred.promise;
When I trigger this Angular service method, I get the following error in my console:
XMLHttpRequest cannot load https://api.parse.com/1/login. Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers.
I'm not sure how to resolve this. Here are the current contents of the common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin, content-type, accept"}
I implement the $http service almost exactly the same for my custom classes without error. The only difference is the URL. Can anyone provide an answer as to why I am getting this error?
EDIT: From this other question, I've gathered that the header field error is the result of the header in the Parse.com response, not in my request. But I am not sure how to proceed now.
EDIT 2: Attached is an image of the HTTP request and response headers that I get when I ping the login API URL.
Are you setting these headers for all http requests somewhere in your angular app?
I'm not sure how to resolve this. Here are the current contents of the
common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin,
These should come from the server only (response headers), so if they are being set somewhere in the request, then the server would error due to extra headers it was not expecting.
So here is the relevant part of the documentation from AngularJS about using the $http dependency.
params – {Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.
data – {string|Object} – Data to be sent as the request message data.
So I conflated params with data. Parse.com expects an URL-parameterized string of the username and password. My confusion was partly because I thought there was a mismatch of request and response headers. But this was not the case.
var deferred = $q.defer();
$http({
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json; charset=utf-8"
},
params: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data, status, headers, config) {
deferred.resolve(data);
}).error(function(data, status, headers, config) {
deferred.reject("error")
});
Additional note: For any Angular developers out there who are concerned about the security of user credentials, you will need to set up SSL for your site to ensure that this data does not fall victim to a man-in-the-middle attack. For information on how to set up SSL with Parse.com, read this article.
If, you do not want to pay for an SSL certificate as DigiCert prescribes (e.g. this app is not for customers, but for internal purposes), check out this article for information on how to create your own SSL certificate and save yourself +$100/year.
I've created an AngularJS service that is hitting the Salesforce REST API directly from the client. However, I haven't been able to get it working due to same origin restrictions. Even when accessing non authenticated REST services and trying both $http, $http.json and Ajax. I've also tried lots of combinations of Json, Jsonp etc.
Given that I've had so many issues I'm thinking that my general approach is incorrect. Perhaps I need to setup a proxy server for this? My backend is Firebase so I don't currently have my own server.
I don't believe that the Salesforce API supports CORs and I cannot change that.
Here is an example of what I tried using $http and Ajax.
return $http.jsonp('https://na1.salesforce.com/services/data/',{
headers: {
'Content-type': 'application/json', 'Accept': 'application/json'
}}).
success(function (data, status, headers, config) {
callback(data);
console.debug(data.json);
}).
error(function (data, status, headers, config) {
console.debug("getVersions: failed to retrieve data: "+eval(data));
});
$.ajax({
url: 'https://na15.salesforce.com/services/data',
type: "GET",
dataType: "jsonp",
beforeSend: function(xhrObj){
xhrObj.setRequestHeader("Content-Type","application/json");
xhrObj.setRequestHeader("Accept","application/json");
xhrObj.setRequestHeader("X-Requested-With", "XMLHttpRequest");
},
success: function (data) {
console.debug(data);
callback(data);
},
error: function(data) {
}
});
You need to go into Remote Settings within SalesForce then CORS and whitelist the domain name...
I had the same issue and it seemed to have resolved the issue.
See if this helps here