Http status 405 while making $http get request - angularjs

I am making ajax get request using angular js $http service to yahoo finance rest api however i am getting http status code 405 in response.
below is the complete stack trace.
index.html#/tab/stock:1 XMLHttpRequest cannot load http://finance.yahoo.com/webservice/v1/symbols/SUZLON.NS/quote?format=json&view=detail.
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 405.
Below is my code to make ajax call.
var config = {
headers : {
'Access-Control-Allow-Origin' : '*',
'Accept' : 'application/json;odata=verbose',
"HOST" : "finance.yahoo.com"
}
};
var promise = null;
promise = $http.get('http://finance.yahoo.com/webservice/v1/symbols/SUZLON.NS/quote?format=json&view=detail',config);
return promise;
I am able to make ajax call to google finance api but yahoo finance api is failing.
Do i need to set any header my config object ?
Or is it something different at Yahoo Rest API side which is returning Http 405 ?
Below code for google api call is working fine without setting any header.
getNseQuote : function(nseScriptCode) {
console.log("Inside nseScriptCode : " + nseScriptCode);
var promise = null;
promise = $http.get('http://www.google.com/finance/info?q=NSE:' + encodeURIComponent(nseScriptCode));
return promise;
}

You can use this extension for chrome link. It allows you to do cross-domain request..Also before you integrate the API with your application test the API URL, see if its working using third party tool like Postman which is best for testing API calls..
Regarding your error
"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource." what it means is that the server is not configured to handle pre-flight request.Pre-flight request is request done by browser in special cases such as when you are requesting data from different domain(when you are doing a request other than GET/POST and using any custom header in your request etc.) for security purpose only (I suppose)..
So, In you case you should use proxy-server which you can make using any open source packages available...In my case I was using node-http-proxy.The browser calls the proxy server and the proxy server fetches the data from the actual server and returns it to the browser..it is easy to make with a little bit of tinkering...

Related

CORS Error happens in api-key request in react js

I want to get api_kye and I use moqui framework in backend , use axios in react js project :
axios.get(SERVER_URL + '/rest/api_key', {
headers: {
Authorization: "Basic " + btoa(username + ":" + password) ,
'Content-Type' : 'application/x-www-form-urlencoded' ,
},
}).then(response => {})
then , when requested the below error happened :
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied origin.
This is not a reactJS error, this is a problem with your backend code, you need to look at the Moqui docs to see how you can allow the origin you are calling from to access your API
Enable CORS in the server side
Let's head back to our server's app.js file.
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send({ "msg": "This has CORS enabled 🎈" })
});
Also check the redirect URL in server side
Refer this link
when ever you send an HTTP request to an API the server response should include your domain in response header otherwise chrome will raise this error: "Access to XMLhttprequest has blocked for origin ...."
so first of all make sure that your domain is included in server code.
if it's included already then the reason could be that server can't process your response correctly. maybe it crashed so the response is corrupted and chrome can't find your domain in response header and it raises that error
So i have a solution for this but you may or may not be able to build it.
CORS is a security feature, you should be receiving requests thru your backend and not the browser directly in general...
IF the data is not sensitive and you want to open an endpoint to the world without getting CORS errors you can do one of two things
Set the CORS headers from the server side. You'll need to understand HTTP requests and headers. you set these from the server. enabling cross origin with * will work.
Build a proxy. I've done this in AWS API gateway, I'll link another post. works good. basically AWS will act as your back end and take the response with CORS blocked. you will then proxy the request and strip the CORS header. When you call the api you will actually call AWS which calls the API, then AWS will pass the response back to you with CORS enabled.
Angular No 'Access-Control-Allow-Origin'
just follow these steps and it will work.

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]

Salesforce and Angular with separate servers

I have two sets of servers:
apache serving up html/js/css pages in the angular flavor
SalesForce backend rest apis serving up Json
Salesforce has OAuth authentication, but it is not letting the javscript even perform an OPTIONS call in order to figure out if it can do the POST call it really wants to:
Is there any way to get around this without a proxy or jsonp?
is the Salesforce APEX Rest API configured wrong? the source domain is already whitelisted...
Update:
so some angular code to make the call:
var config = {
method: 'POST',
url: SalesforceRestApi,
headers: {
Authorization: "OAuth "+authToken,
"Content-Type": "application/pdf"
},
data : caseRequest,
};
var http = angular.element(document.body).injector().get('$http');
http(config).then(function(response){ console.log(response); });
this code here returns the good old Chrome error:
XMLHttpRequest cannot load https://xxx.salesforce.com/services/apexrest/xxx/v1/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://sample.com' is therefore not allowed access. The response had HTTP status code 401.

Access-Control-Allow-Origin error but request goes through

I'm currently deploying a basic API to my live server and I'm running into (what I think is) a CORS problem but there is some behavior going on that I can't explain.
I'm communicating from an AngularJS front-end to a Laravel 5 (+ laravel-cors) back-end.
I started testing with a simple jQuery AJAX call (below) and when I make a request from my local Vagrant environment (http://dev.example.local/test.html) to http://api.example.com/v1/matches I get an error about Access-Control-Allow-Origin. The weird thing is that the request does come through because the information is stored in the database via the Laravel-based API correctly.
$.ajax({
method: 'POST',
url: 'http://api.example.com/v1/players',
data: {
"username": "username",
"first_name": "First",
"last_name": "Last",
"nickname": ""
}
}).always(function(r) {
console.log(r);
});
Error:
XMLHttpRequest cannot load http://api.example.com/v1/players. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://other.example.com' is therefore not allowed access.
The console.log(r) returns {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}
I developed the application locally using a Homestead VM (API) and a Vagrant environment (application) and it's working correctly within these environments...
Some observations:
Each of these requests shows up with Method: POST, Status: 200 OK, Type: xhr in my Chrome Developer Tools.
Tools like Postman and PhpStorm's RESTful service tester correctly execute the request and the data is added without errors.
Any ideas on how to further debug this problem are welcome... I've been trying to wrap my head around this for the entire day now and I just don't know what's causing it.
Your server must return an appropriate Access-Control-Allow-Origin header in the response. For example, if the request is being sent from http://stackoverflow.com, then your server must return this header: Access-Control-Allow-Origin: http://stackoverflow.com. You can determine, server-side, what the origin is by looking at the Origin header on the request. If your server does not return this header in the response, you will not have any access to the properties of the response browser-side (such as the status code, headers, or message body). The Same Origin Policy is at the center of this restriction.
The reason you are not seeing any similar issues when the request is sent by Postman or PhpStorm's RESTful service tester is due to the fact that these services do not send an Origin header with the request, as they are not subject to the Same Origin policy. By default, the browser will append this header to any cross-origin ajax requests, as browsers are subject to the Same Origin Policy. In my previous scenario, the request header would look like this: Origin: http://stackoverflow.com. Browsers that implement the CORS spec are required to add this request header so the server is able to determine if the origin of the request has been whitelisted for cross-origin ajax requests. If this is the case, the server will return the proper Access-Control-Allow-Origin header. If not, it can simply omit the header. Browsers that do not implement the CORS spec will simply refuse to send such an ajax request.
Regarding your bewilderment as to why the request is being sent in the first place, that comes down to a distinction between "simple" and "non-simple" CORS requests. For simple CORS requests, the request will always be sent to the server, but the client/JS will not be able to parse the response without proper acknowledgement from the server. Some CORS requests are not simple, so to speak. These are, for example, DELETE or PATCH requests, or POST/GET requests that contain non-standard headers (such as X-headers or a Content-Type of "application/json" as opposed to "multipart/form-data"). In other words, a request is not simple if it cannot be sent without JavaScript. For example, a <form> submit, or a GET request from a <script src="..."> will always send "simple" requests. For non-simple requests, the browser must "preflight" the request. This means that the browser sends an intermediate request, called a preflight, before the original request. This preflight request is an OPTIONS request. The server must than return headers in the response to this preflight that acknowledge any non-standard properties of the original request. If it does, then the browser will send the original request.
You can read more about preflighting and CORS in general on MDN.

Resources