Can't perform CORS request using Angularjs - angularjs

I am writing my first AngularJS app and have run into a problem with CORS in Angular. Have tried what was mentioned in this reply but still have no luck solving this.
The JS code (main.js) is as follows:
var app = angular.module("app",[]);
app.config(['$httpProvider', function($httpProvider) {
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
app.controller("AppCtrl", function ($scope, $http) {
var postData = "username=demo&password=demo";
$http.post("http://sampleurl.com/login",postData).success(function(data, status, headers, config)
{
console.log(data);
});
});
The Index.html file is:
<!DOCTYPE html>
<html>
<head>
<title>Sample Angular App</title>
</head>
<body ng-app="app" ng-controller="AppCtrl as app">
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
<script src="main.js"></script>
</body>
</html>
The error I get is the following:
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I have tried running this request using Ajax and it works just fine with Ajax. For some reason can't get this to work using Angular. Any idea as to what I am doing wrong here?
Thanks!

Ok. So basically after alot of tinkering around I realised that params were not getting passed using
$http.post("http://sampleurl.com/login",postData)
So I rewrote this request as follows:
$http({
url:'http://sampleurl.com/api',
method:"POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: postData
})
This got the request to go through just fine. Hope this is of help to someone else.
Cheers!

There are two things you will need to do, in the .config you need to put this:
$httpProvider.defaults.withCredentials = true;
And then on your server you need to return an an Access-Control-Allow-Origin header, it would possibly look like this:
Access-Control-Allow-Origin:http://URL_OF_SITE_YOUR_ANGULARJS_APP_IS_AT

If you want to send a CORS request 'withCredentials', you'll need to have your server reply with 'Access-Control-Allow-Origin':'http(s)://your.request.origin'. A wildcard (*) reply will be refused by most browsers for requests with credentials.

I was stuck with the same issue, then I read from this link:
http://better-inter.net/enabling-cors-in-angular-js/
and things worked like a charm :)
var myApp = angular.module('myApp', [
'myAppApiService']);
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);

I had the same problem before and I resolve it by adding this header:
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},

Related

AngularJS routing paths to Express server

I am a beginner to AngularJS, Node and Express.
I can't get even the most basic routing to work with $http.get or $http.post.
Every example I have found online leaves out the relationship between the filenames, the Angular controller path, and the route path in the server. They just show the code without showing the paths and filenames.
Here is my html file: "/programs/static/example.html":
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
</head>
<body>
<div ng-controller="exampleController">
<input type="submit" value="Click me" ng-click="request()">
</div>
<script src="http://code.angularjs.org/1.6.9/angular.min.js"></script>
<script src="/js/example-controller.js"></script>
</body>
</html>
Here is my Angular controller: "/programs/static/js/example-controller.js"
var exampleApp = angular.module('exampleApp', []);
exampleApp.controller('exampleController', function($scope) {
$scope.request = function() {
data="test";
$http.post("/" , data);
};
});
And here is my NodeJS server: "/programs/node-server.js"
var express = require("express");
var app = express();
app.use('/', express.static('./static'));
app.post('/example.html/', function(req, res){
console.log("request received.");
});
app.listen(80);
The problem is that the console of my server doesn't display "request received." This is an example app I built just to post this to Stack Overflow. In my real app I have tried as many different routes as possible. I can get app.get() in my node server to work using simple URLs (not $http methods). But it is obvious from my testing that my Angular controller isn't sending any requests, or else the server isn't receiving them.
Your POST endpoint should not have a file extension in it's name. Any posts to "example.html" will try to return an actual html file named example.html if you have any such file name in your \static folder. Your API endpoints should have clear unique names, with no file extension:
app.post('/test', function(req, res){
console.log("request received.");
});
When using $http.post and passing "/" as the parameter, the actual URL that is posted to will be relative to your current URL. You should always use an absolute URL when posting to a server (unless you know what you are doing). You should also implement the .then and .catch methods. These will help you debug the problem:
$http.post("http://localhost:8080/test", data).then(function(response) {
console.log(response); //this will log a success
}).catch(function(error) {
console.log(error); //this will log the error
});
You are also forgot to inject the $http provider in your controller:
exampleApp.controller('exampleController', function($scope, $http) {
...
});

AngularJS getting strange response from using get on json rest service with no data

This has been frustrating me a bit. I have a restful services giving JSON data running on the link: http://localhost:51133/API/SalesSystem/
So its running locally on my computer. I can get the data from this service with no problem using my WPF based interface.
Another service I am testing with is this one: http://rest-service.guides.spring.io/greeting
But from my own service something seems to go wrong somehow and I cannot figure out what goes wrong. The spring service gives me a response using a response function, but my service gives a response using a success function function. Very confusing.
Response seems to be:
{"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"http://localhost:51133/API/SalesSystem/","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"","xhrStatus":"error"}
I looked it up and it seemed I might be needed to enable Cors, but I am not entirely sure how. I installed it from NuGet, the service is running with Visual Studio, and I added config.EnableCors(); to my WebApiConfig.
My JS script:
angular.module('demo', [])
.controller('Hello', function ($scope, $http) {
$http.get('http://localhost:51133/API/SalesSystem/')
//http://rest-service.guides.spring.io/greeting
//http://localhost:51133/API/SalesSystem/
.then(function (response) {
$scope.hello = 'hello';
$scope.district = response.data;
console.debug(response.data);
console.log(response.data)
}, function success(response) {
$scope.hello = 'hello2';
$scope.district = response;
$scope.rep = response.data;
console.debug(response.data[0]);
$scope.district = response.data[0];
console.log(success.data)
}, function error(response) {
$scope.hello = 'hello3';
$scope.district = error.data;
console.log(error.data)
});
});
My html:
<!doctype html>
<html ng-app="demo">
<head>
<title>Hello AngularJS</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/hello.js"></script>
</head>
<body>
<div ng-controller="Hello">
<li>Id: <button>{{hello}}</button></li>
<li>Area: {{district}}</li>
<ul ng-repeat="obj in hello">
<li>Area: {{obj.area}}</li>
</ul>
<p>The ID is {{rep.Id}}</p>
<p>The content is {{hello.Area}}</p>
</div>
</body>
</html>
I am getting it all to work with my WPF based frontend using this service, not sure why it wont work with AngularJS.
The CORS issue has nothing to do with angular. It has got more to do with the browser .
In layman terms , the cors situation is where the browser does not allow responses of other origins than the url to be processed unless the response has a certain set of headers .Of course, it is a bit more complicated than that .Since the response does not have those headers you are getting the CORS issue
For a quick fix you can disable CORS in your browser .
for example :- if you are using chrome you can run it --disable-web-security flag

$http in angularjs not working

I have a piece of Code in angularjs. If I hard code the value of http response it is displaying the response when I use the http method in angularjs it is not displaying. But I am getting response to that link locally. I dont know where I am wrong. Here is the code
<!DOCTYPE html>
<html>
<head>
<script script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$scope.test = [
{
"done": 2,
"total": 7
}
];
});
</script>
</head>
<body ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="t in test">
<span>{{t.done}}</span>
<span>{{t.total}}</span>
</div>
</body>
</html>
In Script again if i add the below code,its not displaying the values
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response;
});
});
</script>
Try disabling web security of google chrome if you are running google chrome and run your application it will work normally.
Your problem is not with $http rather with CORS.
I've ran into this issue when I was learning angularJS.
Since AngularJS or new frameworks using AJAX extensively there is a small issue called CORS(Cross origin resource sharing) which means we can access a resource from the same domain due to security concerns.
Please refer Understanding CORS.
Web applications are served by servers however you've tried to open your html directly in browser which means you are trying to access a http resource from file protocol which is not allowed as per CORS.
You've two options to use.
Disable web security in google chrome
Run your application in a static server.
Your actual data resides in response.data. So update your scope variable accordingly,
Your controller code,
angular.module('myApp', [])
.controller('MyCtrl', function($scope, $http) {
$http.get("http://localhost:8080/reports/webapi/hello/myresource2")
.then(function (response) {
$scope.test = response.data;
});
});
Hope this solves the issue.
try to add another function for the catching of error response
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response;
}, function(response){
console.log(response)
});
I also went to the similar problem and solved by adding the following HTTP headers at the response of the receiving end.
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin:
You may prefer not to use the * at the end, but only the domainname of the host sending the data. Like *.example.com
But this is only feasible when you have access to the configuration of the server.
You need to add these headers in the server, not in AngularJS
Since you are sending json data through your api .You have to do like this.
<script>
angular.module('myApp', [])
.controller('MyCtrl', function($scope,$http){
$http.get("http://localhost:8080/reports/webapi/hello/myresource2").then(function (response) {
$scope.test = response.data;
});
});
</script>

Unable to Display JSON Data due to CORS in angularjs

I'm trying to create a demo usage of an api in angularjs and I came across this problem.
My Code looks like this:
app.js and index.html
var app = angular.module("ytsApp",['ngRoute','ngResource']);
app.controller('MoviesCtrl',['$scope','movies',function($scope,movies){
movies.get(function(data){
alert(data);
});
}]);
app.factory('movies',['$resource',function($resource){
return $resource('https://yts.ag/api/v2/list_movies.json',{
'sort_by': 'year',
'limit': '15'
},{
'load': {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
});
}]);
<!DOCTYPE html>
<html ng-app="ytsApp">
<head>
<title>The Official Home of YIFY Movie Torrent Downloads - YIFY</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular-resource.js"></script>
</head>
<body ng-controller="MoviesCtrl">
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
This is the result that is getting displayed in the console while I open that page:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://yts.ag/api/v2/list_movies.json?limit=15&sort_by=year. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
I have searched here and there and tried to edit the headers in several ways and couldn't crack it. I appreciate if anyone help me out with this.
You can use jsonp for your demo which supports cross domain:
$http.jsonp('...').then(...);

No 'Access-Control-Allow-Origin' error from local domain to public API

I'm trying to create an app that will retrieve the stock name, asking and buy price from Yahoo Finance API, using Restangular. I'm having a problem with accessing a public API in the local application I'm creating when I do a GET request. This is the URL with parameters that I'm sending:
http://finance.yahoo.com/d/quotes.csv?s=MSFT+GE&f=nab
Using Postman, this get request returns an array which contains the stock name, asking price and buy price of the stock. Doing the request in postman returns the desired information without any errors.
When I do this request in my local, I get the following error:
XMLHttpRequest cannot load http://finance.yahoo.com/d/quotes.csv?s=MSFT+GE&f=nab. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
The HTML code is as follows:
<html ng-app="app">
<head>
<title>Restangular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="//code.angularjs.org/1.2.27/angular-resource.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="//cdn.rawgit.com/mgonto/restangular/master/dist/restangular.min.js"></script>
</head>
<body>
<div ng-controller="IndexCtrl" ng-cloak>
<ul>
<li ng-repeat="person in people">{{person.Name}}</li>
</ul>
</div>
And the JS:
var app = angular.module('app', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://finance.yahoo.com/d');
});
app.controller('IndexCtrl', function($scope, Restangular) {
$scope.people = Restangular.all('quotes.csv?s=MSFT+GE&f=nab').getList();
});
I'm confused by this error because since this is a public API and POSTMAN can access it, I'd assume that the header is already present in the API server. Why would I get this error when requesting from my local?
Any help would be GREATLY appreciated.
Here's me making a JSONP request which fails because it's trying to receive a CSV file. I don't think restangular knows how to read CSV files either which is what you are attempting. I think you need to do the same thing as you are now but using the YQL API instead because I don't think this is going to work.
Anyway here's the code:
http://plnkr.co/edit/GokYqzJ0dXw86C6AM2UP?p=preview
The request (which goes through but fails due to the file type):
app.controller('MainCtrl', function($scope, $http) {
$scope.name = 'World';
$http.jsonp('http://finance.yahoo.com/d/quotes.csv', {
params: {
callback: 'JSON_CALLBACK',
s: 'MSFT GE',
f: 'nab'
}
}).success(function(response) {
console.log(response);
}).catch(function(response) {
console.log(response);
})
});

Resources