Angular making a CORS request - angularjs

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.

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]

Recaptcha request from production server

I am using CORS plugin for chrome and it works fine when uses local machine, but in production server the error occurs:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin is therefore not allowed access.
I understand the problem, that domain server different from domain to send request, also I understand that all users will not add CORS plugin to avoid chrome specific features.
So how do I can off checking for Access-Control-Allow-Origin for concrete post request? Use Angular to send request.
return $http({
method: 'POST',
url: url,
headers:{
'Content-Type': "application/x-www-form-urlencoded"
},
data: $.param(data)
});
I need to avoid this error on prod server.
I just ran into this issue a few days ago and searched everywhere for a response. From what I gathered, the only way to do a cross-domain AJAX request is if you have control of both of the servers hosting each domain. This way you can add the necessary headers in the HTTP requests to allow for cross-domain requests. If you don't have control of both servers, you can POST to a PHP script on your server that can then POST externally and return the info you need. That's how I resolved my issue anyway. hope it helps!

Using https rather than http in angular to get data from server

My application has the following architecture,
An angular 1.5 application has a service which sends request to one of endpoints on server.
The request is received by an nginx server if it is an http request it is redirected to https server.
Then the nginx server redirects my request to upstream node server.
In angular I use the http service to send get and post request.
I don't know if my request along with the data are travelling encrypted by https protocol or as plain text by http protocol from angular to server and back.Can someone please clarify what is going on, the data might contains personal details of user and it is important that it is encrypted.
This question asks the same but is not answered properly.
Thank You.
You can force $http to use HTTPS simply by ensuring that your URL is formatted correctly.
var req = {
method: 'POST',
url: 'https://localhost/api/v1/users', // note: https specified
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
angularjs docs - $https

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.

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