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.
Related
I am invoking a service with $http protocol, but the url that I need to invoke is of https protocol.
As a result I am getting error with code : 403.
Snippet:
return $http({
method: 'POST',
url: 'https://test.com', /* sample url */
headers: some_header,
data: some_data
});
I have tried the same using HTML - form, and it worked there, so I don't think, it's an issue with the url.
I guess, this error is mainly because of $http.
How can one make https call in AngularJS using service or factory?
The 403 Forbidden error is an HTTP status code which means that
accessing the page or resource you were trying to reach is absolutely
forbidden for some reason. This article contains basic troubleshooting
instructions for 403 Forbidden errors.
source
Using Angular's $http service works with https. Here's a basic plunker doing exactly that. It retrieves a resource over https and updates $scope.results with the result.
$http.get('https://run.plnkr.co/plunks/77OOwJ/')
.then(function(data){
$scope.results = data;
})
I am trying to get data from Quandl (https://www.quandl.com/data/YAHOO/MSFT.json) web site. It works perfectly well with all browsers and other REST clients like Postman.
My angular $http call looks quite simple and I've tried quite a few combinations with or without header.
$http({
url: 'https://www.quandl.com/data/YAHOO/MSFT.json',
method: "GET",
headers: {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "SAMEORIGIN",
"X-Rack-CORS": "preflight-hit; no-origin"
}
})
.then(res => {
console.log(res);
});
getting a standard error
XMLHttpRequest cannot load
https://www.quandl.com/data/YAHOO/MSFT.json. Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:2992' is therefore not allowed
access. The response had HTTP status code 405.
However, vendor seems to support CORS
http://help.quandl.com/article/280-does-the-quandl-api-support-cross-origin-resource-sharing-cors
Any ideas?
Thanks
Quandl supports CORS when requesting data through the API. The URL you are trying to use is for the web page of the dataset. To make an API call instead, all that you have to do is find the Quandl code for that dataset and pass it to the API.
You can find the Quandl code at the top right of that page (YAHOO/MSFT in this case). So, the appropriate API call for your request would be https://www.quandl.com/api/v3/datasets/YAHOO/MSFT.json.
You can see full documentation for working with the Quandl API here: https://www.quandl.com/docs/api.
Have you checked if you are using the correct URL? Quandl proposes a different URL for its API. See Quandl - How do I download a dataset using the API
Your URL should be: https://www.quandl.com/api/v3/datasets/YAHOO/MSFT-MSFT-Microsoft-Corporation.json
I am trying to make an Angular application consuming Foreign Exchange (forex) market API.
$http({
method: 'GET',
url: 'http://www.apilayer.net/api/live?access_key=[MY ACCESS KEY]'
}).then(function(response){
console.log(response);
})
I keep getting the following error when I look at the browser console.
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
The weirdest part is that it used to work - I was able to retrieve JSON info from the API call without a problem, but it does not any more.
Is there anyone who can point me to a set of possible causes? Would appreciate it!
If you didn't change anything in your code (say, the path for the api) then it must be one of two thing:
The browser configuration has changed
The api provider has blocked cross domain request, you should contact him, maybe he require callback with jsonp ajax request
I want to call web service from another domain using angular2 typescript.
i am using following code to call api
var req_dict = {
method: RequestMethod.Get,
url: 'http//127.0.0.1:5000/users/',
headers: this.head
}
var options = new RequestOptions(req_dict);
var req = new Request(options);
this.http.request(req).subscribe({});
I hosted my application in http//127.0.0.1:8000. I want to use api from port 5000. when i inspected console , request is going to
http://127.0.0.1:8000/http//127.0.0.1:5000/users/
i want to call just http//127.0.0.1:5000/users/. how can call api by absolute url in angular2 ?
In fact, it's not an issue of TypeScript or Angular2 but a CORS issue. These blog posts could help you to understand in details how this works:
http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
http://restlet.com/blog/2016/09/27/how-to-fix-cors-problems/
To be short, in the case of cross domain request, the browser automatically adds an Origin header in the request. There are two cases:
Simple requests. This use case applies if we use HTTP GET, HEAD and POST methods. In the case of POST methods, only content types with the following values are supported: text/plain, application/x-www-form-urlencoded and multipart/form-data.
Preflighted requests. When the "simple requests" use case doesn't apply, a first request (with the HTTP OPTIONS method) is made to check what can be done in the context of cross-domain requests.
So in fact most of work must be done on the server side to return the CORS headers. The main one is the Access-Control-Allow-Origin one.
200 OK HTTP/1.1
(...)
Access-Control-Allow-Origin: *
To debug such issues, you can use developer tools within browsers (Network tab).
Regarding Angular2, simply use the Http object like any other requests (same domain for example):
return this.http.get('https://angular2.apispark.net/v1/companies/')
.map(res => res.json()).subscribe(
...
);
Hope it helps you,
Thierry
I am very confused. I am trying to use a web service to obtain data. When I put the url into the browser, it works great and returns the json I was expecting.
If angular is a client side framework, why does it not succeed when making the exact same request? The is coming from my browser but the receiving domain still barfs on it.
What am I missing?
Whoever owns the service needs to configure CORS (Cross Origin Resource Sharing), to either allow your particular domain access to the service or to allow all domains to access the service. You then need to configure the correct headers to send your origin and credentials to the origin you are trying to access the service on when making the request so that it can decide if it's gonna let you hit that endpoint or reject the request. Here's the go-to website for an overview and setup guide for CORS: http://enable-cors.org/.
You also need to set the withCredentials flag to true on the http request config object.
Ex.
$http({
url : 'url of service',
method : "POST",
data : {
test : name
},
withCredentials : true,
headers : {
'Content-Type' : 'application/json; charset=utf-8'
}
});
More about the angular configuration for this can be found on the angular docs website for the $http service.