我是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时,我仍然可以看到所需的结果(如上所述)
我甚至尝试在firefox中使用Firebug进行调试,我看到上面的URL在我点击“搜索”按钮时被调用,但响应看起来是空的。有趣的是,在URL下的Firebug中,它显示了
OPTIONS "Above URL"
而不是
GET "Above URL"
您能告诉我,我做错了什么以及为什么我无法访问JSON数据?
谢谢,
答案 0 :(得分:19)
这是因为角度处理CORS请求(跨站点HTTP请求)。 Angular默认添加了一些额外的HTTP标头,这就是为什么您看到OPTIONS
请求而不是GET
。尝试通过添加以下代码行来删除X-Requested-With
HTTP标头:
delete $http.defaults.headers.common['X-Requested-With'];
关于CORS,Mozilla Developer Network上提到了以下内容:
跨域资源共享标准通过添加新HTTP来工作 允许服务器描述原始集合的标头 允许使用网络浏览器阅读该信息。
答案 1 :(得分:3)
我一直在使用$ resource,它也使用$ http。
我注意到当我使用AngularJS 1.0.6时,请求甚至不会出现在Firebug中,但是当使用AngularJS 1.1.4时,Firebug会显示GET请求和200 OK响应以及正确的标题,但是空洞的回应。实际上,标题还显示数据返回,如“内容长度”标题所示,具有正确的内容长度,并将其与我正在使用的成功检索数据的REST客户端插件进行比较。
在进一步怀疑后,我决定尝试不同的浏览器。我最初使用的是Firefox 16.0.1(也尝试过20.0.1),但是当我尝试使用IE 9(和AngularJS 1.1.4)时,代码运行正常,没有任何问题。
希望这可以帮助您找到解决方法。就我而言,我注意到我从未遇到过相对URL的问题,因此我正在更改我的应用程序,以便应用程序和API都在同一个端口上提供服务。这可能是一个AngularJS错误。
答案 2 :(得分:2)
今天我和firefox有同样的问题。 IE工作正常。我一开始并不认为它是cors因为和你一样,我在控制台中没有出现任何错误,并且在我的错误方法中获得了0的状态。在firefox控制台中,我在标题和内容长度中得到200响应,但没有实际的响应消息。 Firefox曾经向您发出有关跨站点脚本的警告,这些脚本可以指向您正确的方向。 我通过在我的api上设置cors解决了这个问题。这真是最好的方式。 如果你只是在你的api上使用GET,你也可以尝试使用jsonp,这是内置于角度的,当你不控制你消耗的api时,这是一个解决方法。
$http.jsonp('http://yourapi.com/someurl')
.success(function (data, status, headers, config) {
alert("Hooray!");
})
.error(function (data, status, headers, config) {
alert("Dang It!");
});
答案 3 :(得分:0)
这是跨站点脚本保护。 尝试使用--disbable-web-security启动谷歌浏览器(通过命令行)。 如果这不起作用也尝试将您的角度内容放入http服务器而不是使用文件协议。 (提示:如果您希望将浏览器专用于--disable-web-security,请使用chrome canary - 当然您也必须设置命令行参数,但两个chrome版本同时运行)。要发布,您必须在服务器上设置一些http标头,提供AngularJS内容,以允许访问twitter api或任何您想要调用的内容。