AngularJS获取JSON时的HTTP状态码为0

11

我正在运行一个$http.get请求获取JSON数据,但状态码是0。我已经下载了相同的JSON文件,并在本地可以正常工作,而且使用Python中的requests库也可以轻松获取JSON数据,但在AngularJS中却不起作用。我不明白的是为什么其他方式都能获取到JSON,但Angular不能。以下是代码片段。

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

当使用本地文件时,它提供JSON并解析它,但否则它将失败并将status1设置为0。

3个回答

21

为了使这一点更清楚,因为在上面的答案中没有直接说明(但在其评论中),可能像我一样,一些Angular新手可能会花费一些时间:

  • Angular的 $resource 将能够在另一个服务器上执行REST动词,该服务器将正确响应(带有 status 200)。然而,Angular仍然会失败,并显示一个难以理解的消息,状态为0。这进一步误导了人们,因为在浏览器的调试器中,您实际上可以看到服务器的响应。

  • 对于跨域请求(至少对于默认的 query() 方法),Angular将对跨域请求执行 OPTIONS 请求,除非相反地指定。通常情况下,服务器不会使用所需的内容(即您的表示)进行回复。每个请求的一种简单方法是将方法指定为 'GET'

  • $resource('http://yourserver/yourentity/:id', {}, {query: {method: 'GET'});
    
    服务器在回应您的REST请求时,必须包含CORS [1]所规定的标头,以允许Angular正确消费响应。这基本上意味着在响应中包括Access-Control-Allow-Origin头,指定来自哪些服务器的请求是被允许的。该值可以是*对于任何与spring-data-rest-webmvc集成AngularJS的人的补充说明: HATEOAS格式的JSON响应将无法被Angular正确消费,反而会产生错误Expected response to contain an array but got an object。解决方法是在$resource的配置中添加isArray:false参数;
    针对spring-data-rest-webmvc场景的CORS配置的简短示例,请参见[2](请参见SimpleCORSFilter)。
    [1]https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS [2]https://spring.io/guides/gs/rest-service-cors/

3
注意,Angular本身不会发出OPTIONS/preflight请求,这是由浏览器完成的。实际上,Angular对此请求一无所知,对于客户端代码而言是完全透明的。 - Ray Nicholus
@ray-nicholus 很有趣。你可以提供任何相关的参考资料吗? - h7r
这是CORS的基本概念。您可以在许多地方阅读有关CORS的信息,例如CORS规范此MDN文章 - Ray Nicholus
对我来说,让事情奏效的(或者在与我们的API开发人员交谈时提供催化剂的)是CORS头缺失。所有奏效的请求都有这些头,他的不奏效的请求(浏览器显示404,Angular显示0)没有这些头。谢谢! - coblr
作为一个特定的例子,今天我在使用ionic/angular和laravel后端构建iOS9应用程序时遇到了这个问题。苹果的传输层安全性存在两个问题。下面的链接和上面的答案帮助了我: https://dev59.com/o10Z5IYBdhLWcg3wnBb_ - Jonny C

2
在你的代码中,状态分配只会在出现错误时发生。你应该能够像这样在调用成功时获取状态:
success(function(data, status, headers, config) {
    $scope.objects = data;
    $scope.status1 = status;
}).error(function(data, status) {
    $scope.status1 = status;
});

但是它仍然会引发错误,并且在从服务器拉取内容时实际上并没有获取到内容,而当它从本地成功获取相同的json时,却没有问题。我想状态0代码并不像我想象的那样重要,真正重要的是无法获取json。 - Corbin Lewis
1
从服务器获取数据?确保您没有调用托管在另一个域上的API。由于JavaScript默认不允许跨域API调用。 - zs2020
那听起来就是正在发生的事情。谢谢。我会在将其推送到服务器之前使用本地文件进行操作。 - Corbin Lewis
没问题。如果你对如何使跨域调用起作用感兴趣,可以查看这个帖子 - zs2020
我有完全相同的问题。但是我尝试从这里给出的w3schools测试URL提取数据。http://www.w3schools.com/angular/angular_http.asp这个http://www.w3schools.com/angular/angular_http.asp服务URL为我的本地angular应用程序加载数据。似乎angular现在允许跨域API调用。那么我的问题是什么? - amilaishere

1
我自己也遇到了类似的问题。一个第三方API通过其他方式返回JSON都很好,但是当通过Angular的$http.get()方法调用时,会出现状态码0的错误。
在我的情况下,并没有CORS问题,相反,我使用的API URL不太正确,服务器发出了301响应。Angular没有遵守重定向。
这是个有益的提示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接