CORS issue with calling Quandl API with angular $http - angularjs

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

Related

Get method is converted to OPTIONS when hitting fetch api in React js

I am trying to hit below api and requires basic auth username and password and method allowed in this is only get
dispatch(requestBegin());
let apiPath = `xxxx/TEST/appservice/api/app/10/10000127201901`;
return fetch(apiPath, {
method: 'get',
headers : {
"contentType":"application/x-www-form-urlencoded",
"Authorization" : 'Basic '+btoa('xxx:xxx'),
},
})
.then((response) => {
dispatch(getEventsEnds(json));
})
.catch((error) => {
dispatch(getEventsEnds());
});
The error loged in console :
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:2200' is therefore not allowed
access. The response had HTTP status code 405. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.
OPTIONS http://xxx/appservice/api/app/10/10000127201901 405 (Method
Not Allowed)
Can anyone please eplain when i m trying to hit get api then why is it showing options
That means your API server does not accept CORS request or requests originating from localhost.
Check out your API documentation but my guess is you won't be able to interact directly with it from your web app.
Your best bet is to use a proxy, you can develop one yourself or use something like node-http-proxy to proxy your API calls. (There are php or python equivalents)
The proxy server will be able to issue the requests and will then forward them to your app.
Suggested further reading: type understanding CORS on google and read more about it.
For local development, check out:
https://github.com/Rob--W/cors-anywhere
This issue occurs when the client api URL and server URL don't match, including the port number. In this case you need to enable your service for CORS which is cross origin resource sharing.
use npm install cors
refer this[refer][1]

API Request with HTTP Authorization Header inside of componentDidMount

I'm very new to React, and to practice, I am trying to build an application that fetches information from the Yelp API, but I'm having trouble getting a response. Yelp Fusion v3 requires an 'access_token'(which I've successfully received as a response in Postman). So to make this request in my application, I am using Axios. When I am making this request inside of componentDidMount(), as a response I get
XMLHttpRequest cannot load https://api.yelp.com/v3/businesses/search?term=sushi&location=Boston. 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:8080' is therefore not allowed access. The response had HTTP status code 500.
Though it may seem that I am incorrectly specifying the access_token and parameters, when running the same code in a separate file(not part of the application), I get the JSON response that I am looking for in my app.
Here is my componentDidMount():
componentDidMount: function () {
axios.get('https://api.yelp.com/v3/businesses/search?term=Sushi&location=Boston',{
headers: {
Authorization: `Bearer ${token}`
}
})
.then(function(res){
console.log(res)
})
.catch(function(err){
console.log(err)
})
},
I've tried the Yelp node module as well, but I am having no luck. Please help!
This error is a Cross-Origin error.
Web browsers have a catch with AJAX requests: They need to be addressed to the same origin or be authorized by the third-party itself, otherwise they are blocked. Since you have no control over Yelp, I suggest you take a workaround.
Available workarounds
You use something like jsonp. This method basically consists in making the request in a <script> tag. The server will wrap the response inside a Javascript script and it will be loaded unto the page. (https://en.wikipedia.org/wiki/JSONP). The server MUST offer this format for that workaround to work.
You use a reverse proxy. You can set NodeJS to act as one. In this setup, you will make your yelp request to your origin who will redirect it to the yelp server. This works because your Node proxy does not have the same limitations as your browser. (ex: https://github.com/nodejitsu/node-http-proxy)
There may be other ways to get around this, but those are popular methods.
Hope this helps.

Angular, Cannot make an an API call probably because of CORS issue

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

angularjs preflight request fails to load data

I am developing a single page application using Angularjs framework.
inside my homeController i use a service call as below
$http({
method: 'POST',
url: 'http://localhost:1530/api/Profile?username=sa&password=da',
data: { Email: "dmytest#test.com", Password: "saas" },
headers: {'Content-Type': 'application/json'}
}).success();
The problem is that when i am making a api call the browser initiates a preflight request with method options instead of post.
Server responds with all required headers.But the actual call is not done.Preflight request initiates only when using "Content-Type:application/json".
I am posting Json data to server.
Is there any way to either prevent the preflight request nor making a successfull api call?
It is working fine on mobile as well as on ajax call.
Thanks in advance.
Depending on you browser, try forceCORS
Chrome: https://chrome.google.com/webstore/detail/forcecors/oajaiobpeddomajelicdlnkeegnepbin?hl=en
Firefox: http://www-jo.se/f.pfleger/forcecors
Also ensure you have enabled CORS on your Server side. I reference here some examples. Please find out what you platform offers:
JAX-RS: http://www.developerscrappad.com/1781/java/java-ee/rest-jax-rs/java-ee-7-jax-rs-2-0-cors-on-rest-how-to-make-rest-apis-accessible-from-a-different-domain/
JAX-RS: http://cxf.apache.org/docs/jax-rs-cors.html
Nodejs: http://www.bennadel.com/blog/2327-cross-origin-resource-sharing-cors-ajax-requests-between-jquery-and-node-js.htm
Hope this helps.

AngularJS: $http.post throws error

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.

Resources