API Request with HTTP Authorization Header inside of componentDidMount - reactjs

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.

Related

How to properly setup the barryvdh/laravel-cors in reactjs

I am currently new in ReactJS and facing problem regarding getting the response of API the console log shows of error of this
Access to XMLHttpRequest at 'https://facebook.github.io/react-native/movies.json' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
they recommend to me that I use the barryvdh/laravel-cors to allow the cors in my API. I will show you guys my front-end code.
componentDidMount() {
axios.get('https://facebook.github.io/react-native/movies.json',{
}).then(function(response){
console.log(response)
})
}
In my logs, I will share here the captured image.
The error is in your Axios request itself, if you clearly see
axios.get('https://facebook.github.io/react-native/movies.json',{})
You've an additional parameter, While you are not passing any headers or other parameters, if you remove the {} then it should work.
axios.get('https://facebook.github.io/react-native/movies.json')
And if you see the results of your console you can see on where it clearly states that OPTIONS request is throwing a 405 status code,
from MDN
The HyperText Transfer Protocol (HTTP) 405 Method Not Allowed response
status code indicates that the request method is known by the server
but is not supported by the target resource.
You'll need to directly access the resource, probably your axios is generating Pre Flight Request with OPTIONS header due to {}, which is being rejected by the resource itself.
You can also try doing it with a simple fetch request,
fetch('https://facebook.github.io/react-native/movies.json')
.then(function(response) {
console.log(response.json())
})
CORS is controlled by backend API and in your case, you don't have control over it which is
https://facebook.github.io/react-native/movies.json.
Browser prevents your code from accessing the response because of the browser can't see Access-Control-Allow-Origin in response.
Things can still get working by making the request through a Proxy can where a proxy sends appropriate CORS header on behalf of your request.
const proxy = "https://cors-anywhere.herokuapp.com/";
const url = "https://facebook.github.io/react-native/movies.json";
fetch(proxy + url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("CORS Error" + url ))
Making a request through a proxy will work this way
CORS proxy will forward your request to https://facebook.github.io/react-native/movies.json
Return response from https://facebook.github.io/react-native/movies.json with Access-Control-Allow-Origin headers.
Now your browser can see Access-Control-Allow-Origin headers present in the response header.
For more detail explanation you can check out this
https://stackoverflow.com/a/43881141/2850383

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]

CORS issue with calling Quandl API with angular $http

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

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

OPTIONS request is not firing with http call through Angular2 Http

I am playing a bit with Angular2 structure and I got to the point where I want to pull information from the server.
Now, my api's domain is different from the FrontEnd app, and I am expecting that the browser will fire OPTIONS request before executing the actual one. However, that is not happening. Instead, what I get is an error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:8080/rrm/api/v1/goals.
(Reason: CORS header 'Access-Control-Allow-Origin' missing).
And my network log looks like this:
My dead simple Angular2 code is as follows:
export class AppComponent implements OnInit {
goals: Object[];
constructor(public authHttp: AuthHttp) {}
ngOnInit():any {
this.getGoals();
}
getGoals() {
this.authHttp.get('http://localhost:8080/rrm/api/v1/goals')
.subscribe(
data => this.goals = data.arrayBuffer(),
err => console.log('Error ', err),
() => console.log('Request Complete')
);
}
}
What am i missing? I am not getting options request on the server and I don't see it in the browser...
Thanks,
In fact, there are two main cases in CORS:
Simple requests. We are in this case if we use HTTP methods GET, HEAD and POST. In the case of POST method, only content types with following values are supported: text/plain, application/x-www-form-urlencoded, multipart/form-data. Even if you're in these case and if you use a custom header (a header that you define by your own in your request), you'll fall into the preflighted request.
Preflighted requests. When you aren't in the case of simple requests, a first request (with HTTP method OPTIONS) is done to check what can be done in the context of cross-domain requests.
In your case, you're in the first case (simple request).
Moreover your GET request should define a Access-Control-Allow-Origin header in its response not to have the error. This will allow the browser to determine if you're (localhost:3000 for example) able to execute the request.
This article could interest you:
http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
The OPTIONS is only sent befor every POST request. For GET requests an OPTIONS preflight request is only sent if you have custom headers like auth-headers.
See also Why am I getting an OPTIONS request instead of a GET request?

Resources