HTTP Status 0 from AngularJS Get for JSON

2019-02-08 18:04发布

问题:

I'm running a $http.get for a JSON and am getting a status of 0. I've downloaded the same JSON and the get works locally, and in Python using the requests library I can get the JSON no problem, but in AngularJS it's not working. What I don't understand is why angular isn't getting it but everything else is. Code snippet below.

function AgentListCtrl($scope, $http) {
  $http.get('http://foo.bar/api/objects').success(function(data) {
  $scope.objects = data;
}).error(function(data, status) {
  $scope.status1 = status;
});

This provides the JSON and parses it when using a local file, but otherwise it fails and sets status1 to 0.

回答1:

In your code, the status assignment only occurs when the error happens. You should be able to get the status when the call was made successfully like this:

success(function(data, status, headers, config) {
    $scope.objects = data;
    $scope.status1 = status;
}).error(function(data, status) {
    $scope.status1 = status;
});


回答2:

Just to make this clear since is not directly stated in the above answer (but in its comments) and, like me, some Angular newbies may be spending some time on this:

  • Angular's $resource will be able to execute a REST verb on another server, which in turn will respond correctly (with a status 200). Angular will nevertheless fail with a cryptical message, identifyiable by the status 0. It is further misleading since, in a browser's debugger, you may actually see the server's answer.

  • Angular will do an OPTIONS request on a cross-domain request (at least for the default query() method) unless specified on the contrary. Usually the server will not answer with the desired content (i.e. your representation). One simple way of doing this per request is specifying the method to be 'GET'.

    $resource('http://yourserver/yourentity/:id', {}, {query: {method: 'GET'});
    
  • The server answering your REST requests MUST include the headers specified by CORS [1] in order to allow Angular to consume properly the response. Essentially this means including the Access-Control-Allow-Origin header in your response, specifying the servers from where the request comes from, that are allowed. This value may be *.

Complementing this answer for anyone integrating AngularJS with spring-data-rest-webmvc:

  • the HATEOAS json formatted response will not be properly consumed by Angular, producing instead the error Expected response to contain an array but got an object. This is solved by adding the isArray: false parameter to the $resouce's configuration;

  • a very to-the-point example of configuring CORS for the spring-data-rest-webmvc scenario is presented at [2] (see the SimpleCORSFilter)

[1] https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS

[2] https://spring.io/guides/gs/rest-service-cors/



回答3:

I was having a similar problem myself. A third party API that returns JSON just fine through every other means was failing with status 0 when called through Angular's $http.get() method.

In my case there wasn't any CORS problem. Instead, the URL I was using for the API was not quite right and the server was issuing a 301 response. Angular wasn't respecting the redirect.

Word to the wise.