angularjs preflight request fails to load data - angularjs

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.

Related

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

AngularJS OPTIONS request to Web API lost

I am trying to make a post request from AngularJS to WebAPI on a different domain.
$http({
method: 'POST',
url: 'http://www.test.com/api/app/controller',
data: postdata,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(response) {
// Do stuff
}, function() {
// Show error
})
.finally(function() {
// Cancel loading indicator
});
I believe Web API is setup correctly to handle CORS requests. If I make a CORS OPTIONS request using Chrome Advanced REST client, the correct headers and a 200 response code are returned.
When I make the POST call above, a preflight OPTIONS request is made. This always times out with a 504 code. The logging in my Application_BeginRequest is never hit (which it is when calling from Chrome plugin).
What is the difference between calling from AngularJS and the Chrome plugin? Both are being run from the same machine and AngularJS is running in an application on localhost. The same headers are being set in both calls.
This was a stupid mistake on my behalf. I am answering the question (rather than deleting) in case somebody does the same.
I was pointing to a service containing a typo:
url: 'http://www.test2.com/api/app/controller',
Instead of:
url: 'http://www.test.com/api/app/controller',
My CORS pre-flight request was working without an issue, it was just never getting to the right server.

Using secure https and returning data

I am using a 3rd party API as a booking portal. I am using Angular $http to post to a php curl script on my site that will make the actual call cross site to the API.
factory.bookingRequest = function(reservationData){
return $http({
method: "post",
url: "api-book.php",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: reservationData
}).then(function(response){
return response.data;
});
};
1)
Does the Angular page that is posting to the php page need to be via https also? Or just the script that is responsible for sending the data outside of the site?
2) Also when I get the response back, it has a confirmation number and other details that they have said also need to be via HTTPS.
How would this best be handled? Could I have this as a session cookie and return it to a /booking/confirmation route or return this back to the same page but using ng-show or ng-hide to show confirmation details?
3)
Also when I am sending form data from my Angular route to my Php page in the network tab in chrome dev tools I can see all the information that is getting sent to my php page (Request payload in the headers tab). Just wanted to make sure this was ok also?

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