Angular simple JSON request - javascript

this will probably make me look like a total beginner and I am when it comes to angular, but here's my question:
I'm trying to make a simple request to a .JSON api but I just keep getting the error status code 0.
var dataUrl = 'http://www.reddit.com/r/pics/comments/1ua1nb/.json?limit=2';
$http({method: 'GET', url: dataUrl}).
success(function(data, status, headers, config)
{
window.alert('success:' + status);
}).
error(function(data, status, headers, config) {
window.alert('error:' + status);
});
Update:
I checked the javascript console via the browser and got these error messages:
event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
Failed to load resource: the server responded with a status of 501 (Not Implemented) http://www.reddit.com/r/pics/comments/1ua1nb/.json?limit=2
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ... is therefore not allowed access. http://www.reddit.com/r/pics/comments/1ua1nb/.json?limit=2
XMLHttpRequest cannot load http://www.reddit.com/r/pics/comments/1ua1nb/.json?limit=2. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin ... is therefore not allowed access.

You are trying to do a cross-domain request. This is forbidden by browser (it will only let you make requests to the same domain as your page was initially loaded from). This is not specific to angular, but just ajax requests in general.
You can read about it here:
http://en.wikipedia.org/wiki/Same-origin_policy
There are several ways around it, such as JSONP and CORS. Both require server-side support. You would have to look at the service you are calling to see which it might support.
You can read about how to do a JSONP request here:
http://docs.angularjs.org/api/ng.$http

You are not allowed to access resource on another website.
You need to use jsonp.
This is an un-tested modified code of yours, please try it to see whether it's working or not:
var dataUrl = 'http://www.reddit.com/r/pics/comments/1ua1nb/.json?jsonp=JSON_CALLBACK&limit=2';
$http.jsonp(dataUrl).
success(function(data, status, headers, config)
{
window.alert('success:' + status);
}).
error(function(data, status, headers, config) {
window.alert('error:' + status);
});
more to read:
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Related

AngularJS Refused to set unsafe header "Cookie"

I am using an AngularJS application to make a call to an API using $http. The call to $http is originating from localhost:9000. The API is endpoint is available at localhost:9100/API/v1.0/context...
I am getting an error message saying "Refused to set header Cookie". From what I have read, the browser sets these headers for security reasons and these cannot be configured. According to the similar question heresimilar question here, I have tried enabling crossDomain:true and withCredentials:true but to no effect.
Any answer on why this is happening would be appreciated.
EDIT: Here is the code
$http({
method: method,
url: urlpoint,
headers:headers,
params: query,
crossDomain: true
})
.success(function(data, status, headers, config) {
if (!data || data.length == 0)
data = $rootScope.getLocaleValue("EMPTY_RESPONSE");
operation.result.data = data;
$scope._afterMakeTestCall(operation, status,
headers, config);
});
And in the headers field, I have set
headers['Cookie'] = 'cookieValue="something";';
After a long time of searching, I came across references stating that browser will not allow to set the Cookie header due to security vulnerabilities. It can only be done through headless browsers.

angularJS sending OPTIONS instead of POST

Im stuck at this 2 days I can not find a solution.
When im doing an AngularJS POST it Sends OPTIONS in the header and returns error from the API the code looks like this nothing special.
$http.defaults.headers.post["Content-Type"] = "application/json";
$http.post(URL, JSON.stringify(data)).
success(function(data, status, headers, config) {
alert(data);
error(function(data, status, headers, config) {
console.log("Error");
});
CORS is enabled on the API it has the Headers, when i do POST with fiddler or POSTMan in Chrome it works fine only when i use angularJS post it won't go thru.
why do i get OPTIONS /SubmitTicket HTTP/1.1 instead of POST?
What do i need to do to POST ? I have read about it it says something like CORS is adding OPTIONS header but why?
When you invoke the CORS requests, the browser always sends the OPTIONS request to server to know what methods are actually allowed. So this is the desired behaviour. This is so called: "Preflighted request", see: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ (section: "Preflighted requests")
Therefore in your case, you have to allow the OPTIONS method in 'Access-Control-Allow-Methods' header of your CORS filter.
My understanding is that angular initially sends an OPTIONS request to the server in order to ask the server if the full request is permissable.
The server will then respond with Headers specifying what is and is not allowed.
I guess this might be an issue with the server returning the wrong CORS headers.
You said that the server returns an error please post that error here.
See Preflighted CORS request at: http://www.staticapps.org/articles/cross-domain-requests-with-cors
and
AngularJS performs an OPTIONS HTTP request for a cross-origin resource
// Simple POST request example (passing data) :
$http.post('/someUrl', {msg:'hello word!'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Should only need to do this code to get it to work:
angular.module('TestApp', [])
.factory('someService', ['$http', someService]);
function someService() {
var service = {
save: save
};
var serviceUrl = '/some/Url';
return service;
function save(data) {
$http.post(serviceUrl, data)
.success(function(data, status, headers, config) {
alert(data);
})
.error(function(data, status, headers, config) {
console.log("Error");
});
}
}
Then pull your someService into your controller and use:
someService.save(data);

CouchDB XMLHttpRequest Error

I am using Angular to connect to a server running CouchDB that I have set-up. When ever I run the code I get the error:
"XMLHttpRequest cannot load http://ip:5984/_all_dbs. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://morris-tibet.codio.io' is therefore not allowed access."
I have set-up the origins and cannot understand what the problem could be.
Here is the code I am using to connect:
myApp.controller('OverviewCtrl', ['$http',
function($http) {
var self = this;
self.dbNames = [];
$http({
url: 'http://ip:5984/_all_dbs',
method: 'GET'
}).
success(function(data, status, headers, config) {
self.dbNames = data;
console.log(self.dbNames);
}).
error(function(data, status, headers, config) {
self.dbNames = ['Something wrong with your code!', ''];
console.log(self.dbNames);
})
}
]);
In the code the ip address has been replaced for security reasons.
EDIT:
I was told it may be an issue with my CORS, here is an image showing my cors for the server:

AngularJS 'No 'Access-Control-Allow-Origin' header is present on the requested resource' error

I am using AngularJS 1.2.20.
Whenever I use the $http service to access a zip file from a URL (different domain/server), it gives me an error as following:
XMLHttpRequest cannot load http://localhost/ABC/updates.zip. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
I've tried setting the following in the config of my module:
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
$httpProvider.defaults.headers.common["Accept"] = "application/json";
$httpProvider.defaults.headers.common["Content-Type"] = "application/json";
But this still throws the error.
My code snippet is :
$http({method: 'GET', url: paths.categoryUpdateURL}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
alert("download Complete")
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert("error")
});
What should be done to prevent this?
Unless the server provides a JSONP API, or allows configuring the Access-Control-Allow-Origin response attribute, you can't do anything besides requesting that your server requests the ZIP file, as the browser won't allow it.

AngularJS: Cannot send POST request with appropiate CORS headers

I'm creating a web app using AngularJS. To test it, I'm running the app in a NodeJS server, using angular-seed template.
In this app, I need to send a JSON message to another host, via POST request, and get the response, so, I'm using CORS.
My request is done by implementing a service that uses AngularJS http service (I need the level of abstraction that $http provides. So, I don't use $resource).
Here, my code. Please pay attention to the fact that I modify $httpProvider to tell AngularJS to send its requests with the appropriate CORS headers.
angular.module('myapp.services', []).
// Enable AngularJS to send its requests with the appropriate CORS headers
// globally for the whole app:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
/**
* Just setting useXDomain to true is not enough. AJAX request are also
* send with the X-Requested-With header, which indicate them as being
* AJAX. Removing the header is necessary, so the server is not
* rejecting the incoming request.
**/
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]).
factory('myService', function($http) {
return {
getResponse: function() {
var exampleCommand = JSON.stringify({"foo": "bar"});
// This really doesn't make a difference
/*
var config = {headers: {
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Accept',
'Content-Type': 'application/json'
}
};
*/
//return $http.post(REMOTE_HOST, exampleCommand, config).
return $http.post(REMOTE_HOST, exampleCommand).
success(function(data, status, headers, config) {
console.log(data);
return data;
}).
error(function (data, status, headers, config) {
return {'error': status};
});
}
}
});
The problem is I can't make it work. I always get this error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at REMOTE_HOST. This can be fixed by moving the
resource to the same domain or enabling CORS.
But if I do a simple jQuery AJAX call like this:
$.ajax(REMOTE_HOST,
{
dataType: "json",
type: "POST",
data: exampleCommand,
success: function(data) { console.log(data); },
error: function(request, textStatus, errorThrown) { console.log("error " + textStatus + ": " + errorThrown);}
});
It works fine.
So, my questions:
- How do I allow cross-site requests in an AngularJS running under NodeJS?
UPDATE: Thanks to Dayan Moreno Leon's response.
My problem is I need to add cors support to my server. I'm using NodeJS http-server for development and lighttpd for production.
- Why does the simple jQuery POST request work but AngularJS POST request doesn't?
I guess jQuery AJAX requests are cross-domain by default. Not really sure yet.
Many thanks in advance
CORS is not handled on the client but in the server you need to allow CORS on your nodejs app where your angular app is trying to POST. you can try using cors module if you are using express
https://www.npmjs.org/package/cors
other whise you need to check for the options method and return 200 as a response
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Why does the simple jQuery POST request work but AngularJS POST request doesn't?
jQuery uses simple requests while AngularJS uses preflighted requests
In your angular code you can add set Content-Type to application/x-www-form-urlencoded and encode your data using $.param

Categories

Resources