I am making a $get request to a secure server in Angular. The problem is this is an internal server (which I have no control over) with a bad certificate and as a result I am getting mixed content error messages and my browser is not allowing the response to be displayed for security reasons.
Anything I can do to request data by HTTPS but also make sure I accept a non secure response?
$.get('https://internal.domain.com' + '' + $scope.account, function (data, status) {
_.forEach(data, function (item) {
$rootScope.hotNews.push(item);
});
});
Sadly, I found out its not possible... :(
Related
I'm trying to call an endpoint using $http.get but the call fails each time. The error status just returns -1.
How can I get a more detailed error message?
Maybe I'm making some mistake in my JavaScript but I seem to be able to call other end points fine. The request that fails for me is:
$http.get("http://www.bloomberg.com/markets/api/security/currency/cross-rates/EUR,AUD")
.success(function (data) {
alert(data);
return data;
}).error(function (status){
alert("Error status : " + status);
});
It seems that the Bloomberg API doesn't include the Access-Control-Allow-Origin header in their response. This makes it impossible for an Angular web based app to access the API since most browsers respect CORS:
If it is a CORS issue as Nasreddine suggested then you can use a CORS plugin in google chrome for testing purposes. It will get resolved when you host it in a server.
Coming to your Question a response of -1 usually indicates a timeout of request/ Server not responding.
I have a weird problem with AngularJS's $http service which, as far as I can see, no one else has.
Every time I use $http.post() to sent cross domain requests, I can see in the developer tools (network pane) that two different requests are being sent: one, without any data, and immediately after that another one is sent which has all the data and returns with the correct response from the server.
Here's an example:
$http.post(url+'getSiteList.php', {session_id: $scope.session_id(), withCredentials: true})
.success(function(data, status, headers, config) {
console.log(data);
....
Does anyone know what's causing this? I checked the code, and the $http.post method is only being called once.
It's all about how browsers manage CORS. When making a cross-domain request in angular, the browser will automatically make a HTTP OPTIONS request to the specified URL/URI it is called as "pre-flight" request or "promise".
As long as the remote source returns a HTTP status code of 200 and relevant details about what it will accept in the response headers, then the browser will go ahead with the original JavaScript call.
Is it possible to use basic auth with the following snippet to make a simple post request to a site running locally?
app.controller('post', function($scope, $http) {
$http.post("http://localhost:8888/angular//wp-json/posts", {'title':'Posting from Angular'})
.success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
document.getElementById("response").innerHTML = "It worked!";
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
document.getElementById("response").innerHTML= "It did not work!";
alert(status)
});
});
When you say basic auth, do you mean HTTP Basic Authentication?
If that's what you mean: then NO. HTTP Basic Authentication requires that your client (in this case, your web browser) needs to know your API keys and be able to send them over the network to your server. Since you're running Angular inside of a web browser, this means that any user visiting your site would theoretically be able to view your API credentials in plain text by inspecting the browser's Javascript console.
This is a HUGE security risk.
What you want to do instead is use a protocol like OAuth2 with the Password Grant (more info here: https://stormpath.com/blog/token-auth-spa/).
OAuth2 allows you to basically do this:
Have a user log into your application with a username/password.
When the login is successful, a token will be returned and stored in a web browser cookie that is HIDDEN FROM JAVASCRIPT.
Then you can use Angular to POST to your API service, as the browser will automatically attach the relevant token API credentials in the HTTP Authorization header automatically.
Your server can then grab the token out of the HTTP Authorization header, and validate the credentials in this way.
This is the only safe way to access an authenticated API service from a browser.
I'm stacking on a shit problem and can't find a solution... maybe has someone an idea.
I have a rest api based on sails.js and send a post request via Angular.js - works fine I get all response data!
But im unable to read the header cookie. The cookie is always null...
In the header should be a 'Set-Cookie'. If I call the same function with a Rest tool I get the cookie header.
I'm working local host port :8000. The rest api is on port :1337
$http.post(url, json)
.success(function(data, status, headers, config) {
console.log(headers('Server'));
console.log(headers('Set-Cookie'));
})
.error(function(data, status, headers, config) {
console.log("error");
console.log("status " +status);
console.log("status " +angular.toJson(data));
});
Any idea?
Cheers!!
First of all, you should never need to get the set-cookie header in Javascript; the browser handles setting the cookie for you. If you want to check if the cookie was part of the response, it's better to use your browser's development console.
More to the point, the issue here is that the cookie is not going to be set at all since this is a cross-origin AJAX request (different ports counts as a different origin) and you probably haven't set the CORS settings in Sails to allow the request through.
The full documentation for CORS in Sails is here. The easiest way to get started with testing it is to open your /config/cors.js file and set allRoutes to true; this will allow all CORS requests to go through unimpeded, regardless of their origin or the route they're trying to access. Once you've got that working, you can use the more fine-grained settings to lock down access if you want.
Note that by default, only a very few response headers from a cross-origin request will be made available via Javascript, of which set-cookie is definitely not one!
I am using Request Bin to post some data. In my controller, I have the following code:
$http.post('http://requestb.in/redacted', fooBar).
success(function(data) {
$scope.fooBarPostedSuccess = true;
}).
error(function(err) {
console.log("Error while posting to Request Bin");
console.log("Error Info : " + err);
});
This is triggered by means on a button on the UI. Now when this gets triggered, the data is not posted to Request Bin and I get this error:
XMLHttpRequest cannot load http://requestb.in/redacted.
Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.
How do I post data to request bin through an AngularJS controller? Also, what does the above error mean?
EDIT : I wish to add here that I am using Node.js with AngularJS. Is this something to do with Node perhaps?
Ah yes... you are dealing with cross-domain scripting issues. This is not an AngularJS problem, but a browser security limitation and a VERY common friction point.
You cannot POST/PUT/DELETE to another domain (different from the one which is hosting -- localhost in your case) without doing some Cross-Origin Resource Sharing (CORS). You are limited to GET for a cross-domain HTTP request.
You have two options:
See if your API supports any cross-domain capabilities. This might be via CORS or it might be via an overloaded GET API or JSONP.
Proxy requests through your server. Since you are using Node.js, proxying REST through your server is extremely simple... you just need to set up a route handler (like /api/redacted) in your Node.js server and then make a new request to your actual API server with something like Restler (NPM package) and return the result back to your client.
Hope this helps!
EDIT:
Your API supports JSONP (Your API Docs). You should be able to use Angular's JSONP function to access your API's JSONP capabilities. (Angular.js JSONP docs).
Since you want to be able to POST to the service, you will need to use the second approach.
CORS allows both GET and POST
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
http://www.w3.org/TR/cors/
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
Now, that that's out of the way...
I too have found that angular's $http won't let me POST cross domain. I was suspicious about that though because I have jquery ajax calls in other projects that can post cross domain just fine. So, I swapped my $http POST with $.ajax POST and that worked.
// $http({
// url: url,
// method: "POST",
// data: data
// })
// .success(successCallback)
// .error(errorCallback)
// ole reliable
$.ajax({
type : "POST",
url : url,
data : data,
success : successCallback,
error : errorCallback,
cache : false,
dataType : 'json',
})
You can use PutsReq instead of RequestBin. PutsReq supports CORS.