AngularJS问题:$http.get无法工作

20

我对AngularJS还很陌生,尝试按照AngularJS网站文档中给出的$http.get示例进行操作。

我有一个REST服务,当调用它时,返回的数据如下:

http://abc.com:8080/Files/REST/v1/list?&filter=FILE


 {
  "files": [
    {
      "filename": "a.json",
      "type": "json",
      "uploaded_ts": "20130321"
    },
    {
      "filename": "b.xml",
      "type": "xml",
      "uploaded_ts": "20130321"
    }       
  ],  
 "num_files": 2}

我的 index.html 文件的一部分内容如下所示:

<div class="span6" ng-controller="FetchCtrl">
    <form class="form-horizontal">
        <button class="btn btn-success btn-large" ng-click="fetch()">Search</button>
    </form>
      <h2>File Names</h2>
      <pre>http status code: {{status}}</pre>
     <div ng-repeat="file in data.files">
      <pre>Filename: {{file.filename}}</pre>
    </div>

我的js文件如下所示:

function FetchCtrl($scope, $http, $templateCache) {
  $scope.method = 'GET'; $scope.url = 'http://abc.com:8080/Files/REST/v1/list?&filter=FILE'; 
  $scope.fetch = function() {
    $scope.code = null;
    $scope.response = null;

    $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
      success(function(data, status) {
        $scope.status = status;
        $scope.data = data;
      }).
      error(function(data, status) {
        $scope.data = data || "Request failed";
        $scope.status = status;
    });
  };      
}

但是当我运行它时,我看不到任何关于文件名的结果,并且我看到http状态码为0

当我在浏览器中运行

http://abc.com:8080/Files/REST/v1/list?&filter=FILE
时,我仍然可以看到期望的结果(如上所述)

我甚至尝试使用火狐浏览器中的Firebug进行调试,当我点击“搜索”按钮时,我看到上面的URL被调用,但响应似乎为空。有趣的是,在Firebug下的URL下,它显示

   OPTIONS "上面的URL" 

而不是

   GET "上面的URL"

请告诉我,我做错了什么以及为什么我无法访问JSON数据?

谢谢,


嘿,我知道已经有一段时间了,但你最终解决了这个问题吗?被接受的答案在Firefox或Chrome中对我不起作用。它仍然调用OPTIONS。 - tbogatchev
4个回答

19

这是因为Angular处理CORS请求(跨站HTTP请求)的方式。Angular默认会添加一些额外的HTTP头,这就是为什么你会看到OPTIONS请求而不是GET请求的原因。尝试通过添加以下代码来移除X-Requested-With HTTP头:

delete $http.defaults.headers.common['X-Requested-With'];

关于CORS,在Mozilla开发者网络中提到:

Cross-Origin Resource Sharing标准通过添加新的HTTP头来允许服务器描述可以使用Web浏览器读取该信息的源集。


它部分地工作了,这意味着在Firebug中我可以看到在从angular.min.js中删除<pre>"X-Requested-With":"XMLHttpRequest"</pre>后的'GET "URL"'(请告诉我是否正确)。但是我仍然无法在HTML页面中获得任何响应。不确定我是否做错了什么。 - SL101
当我通过Firebug检查时,状态代码显示为“200 OK”,但响应中没有任何内容。但是当我只运行REST调用时,确实会得到状态代码为“200 OK”的正确响应。 - SL101
现在您的调用正在工作,请检查是否调用了“success”或“error”函数。尝试放置一个警报以查看执行哪个函数。您的HTML代码似乎很好,在此处查看其实际效果:http://plnkr.co/edit/TLRr1VdADdDHoGikhHu3 请记得单击极右侧的“预览”图标。 - Aziz Shaikh
2
错误函数被调用,状态为0且数据为空。我尝试替换$scope.url = 'http://search.twitter.com/search.json?q=angularjs';(这是Twitter的标准JSON REST API)。但结果仍然相同。不确定出了什么问题? - SL101
如果我将$scope.method = 'GET'替换为$scope.method = 'JSONP',那么它会在Firebug中显示响应,但在JS代码中仍然调用错误部分。 - SL101

3

我一直在使用$resource,并且它也使用了$http,但是出现了问题。

我注意到,当我使用AngularJS 1.0.6时,在Firebug中请求甚至都不会显示,但是当我使用AngularJS 1.1.4时,Firebug会显示GET请求和200 OK响应以及正确的头信息,但是响应为空。事实上,头信息还显示数据已经返回,如“Content-Length”头信息具有正确的内容长度,并将其与我正在使用的REST Client插件进行比较,该插件成功地检索数据。

更加怀疑之后,我决定尝试另一个浏览器。我最初使用Firefox 16.0.1(还尝试了20.0.1),但是当我尝试IE 9(和AngularJS 1.1.4)时,代码可以正常工作,没有任何问题。

希望这可以帮助您找到解决方法。在我的情况下,我注意到相对URL从未出现过此问题,因此我正在改变我的应用程序,使应用程序和API在同一端口上提供服务。这可能是AngularJS的一个错误。


2
今天我在使用火狐浏览器时遇到了同样的问题,但在IE浏览器中却没有问题。一开始我并没有想到这是跨域资源共享(CORS)的问题,因为和你一样,在控制台中我没有看到任何错误,并且在我的Angular错误方法中返回了状态码0。但是,在火狐浏览器的控制台中,我的头部信息显示返回了状态码200和内容长度,但没有实际的响应消息。以前,火狐浏览器会发出有关跨站点脚本的警告,指引你走正确的方向。 我通过在API上设置CORS来解决了这个问题,这确实是最好的方法。 如果您只是使用GET请求您的API,您也可以尝试使用jsonp,这是Angular内置的一种CORS解决方案,适用于您无法控制正在使用的API的情况。
$http.jsonp('http://yourapi.com/someurl')
    .success(function (data, status, headers, config) {
        alert("Hooray!");
    })
    .error(function (data, status, headers, config) {
        alert("Dang It!");
    });

0

这是跨站脚本保护。 尝试使用命令行启动Google Chrome并添加--disbable-web-security参数。 如果这不起作用,还可以将您的Angular代码放入HTTP服务器中,而不是使用文件协议。(提示:如果您想要一个专门用于--disable-web-security的浏览器,请使用Chrome Canary - 当然,您也必须设置命令行参数,但两个Chrome版本同时运行)。对于发布版本,您需要在提供AngularJS内容的服务器上设置一些HTTP头以允许访问Twitter API或其他您想要调用的内容。


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