从angularjs调用REST服务时localhost上的CORS问题

Bhr*_*mar 10 javascript rest wcf cors angularjs

我正在学习angularJS并尝试在我的应用程序中实现它.

我在localhost IIS上托管了RESTful WCF服务.它定义了一个GET方法来获取文档列表:http:// localhost:70/DocumentRESTService.svc/GetDocuments /

现在我尝试在我的角应用程序中使用此服务并显示数据.以下是代码:HTML:

<html>
    <script src="../../dist/js/angular/angular.min.js"></script>
    <script src="../../assets/js/one.js"></script>
    <body ng-app="myoneapp" ng-controller="oneAppCtrl">
                {{"Hello" + "AngularJS"}}
        <hr>
        <h1> Response from my REST Service </h1>
        {{hashValue}}

        <hr>
        <h1> Response from w3school REST Service </h1>
        {{names}}


    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

JS:

angular.module('myoneapp', [])
    .controller('oneAppCtrl', function($scope,$http){
        $scope.documentValue = {};

        $http({method: 'GET',
                url: 'http://localhost:70/DocumentRESTService.svc/GetDocuments/',
                headers:
                        {
//                          'Access-Control-Allow-Origin': 'http://localhost'
                        }                   
               })
            .success(function(data){ alert('Success!'); $scope.documentValue=data;})
            .error(function(data){ alert('Error!'); $scope.documentValue=data; alert('Error!' + $scope.documentValue);})
            .catch(function(data){ alert('Catch!'); $scope.documentValue= data;});

        $http.get("http://www.w3schools.com/angular/customers.php")
            .success(function(response) {$scope.names = response.records;});            
});
Run Code Online (Sandbox Code Playgroud)

奇怪的行为是这个代码在IE11中运行得很好,而它不能在Chrome/Firefox中运行.

以下是chrome中的响应:(对于我的REST服务),而来自w3schools的REST服务工作正常.

{"data":null,"status":0,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":" http:/ /localhost:70/DocumentRESTService.svc/GetDocuments/","headers":{"Accept":"application/json,text/plain,/ "}},"statusText":""}

控制台显示以下错误消息.

  • [Chrome控制台:从文件系统打开]

XMLHttpRequest无法加载http:// localhost:70/DocumentRESTService.svc/GetDocuments /.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许Origin'file://'访问.

  • [Chrome控制台:使用Brackets托管]

XMLHttpRequest无法加载http:// localhost:70/DocumentRESTService.svc/GetDocuments /.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此,不允许来源" http://127.0.0.1:55969 ".

  • [Firefox控制台:]

跨源请求已阻止:同源策略禁止在http:// localhost:70/DocumentRESTService.svc/GetDocuments /中读取远程资源.这可以通过将资源移动到同一域或启用CORS来解决.

这里的问题很少:

  1. 为什么localhost或我的machineName被认为是跨域请求?我在同一个域名,不是吗?
  2. 我的服务端是否需要进行任何更改才能启用此行为?如果是,在WCF服务中的位置?(基于我在这里阅读的内容)
  3. JSONP在这种情况下有用吗?如果是,我将如何使用它?它是否适用于需要自定义标题的请求?(不知道它是什么,但是在重新构建时发现了许多提到这个的答案.阅读链接会有所帮助.)

任何帮助或指示都会有所帮助.

PS:

  • IDE:Brackets,如果重要的话.
  • AngularJS v1.4.3
  • 我已经提到了涉及类似问题(CORS)的各种stackoverflow问题,其中涉及$ resource,$ provider,$ config,还有一些与删除一些标题并添加一些标题值有关.我对此有点天真 - 任何对此的引用都会有所帮助.

Bhr*_*mar 8

我可以解决这个问题.有几种方法可以这样做 - 我正在记下我尝试过的所有内容和他们的参考资料.

回答Ques1.

'Why is localhost or my machineName considered to be a cross-domain request?'
Run Code Online (Sandbox Code Playgroud)

正如@charlietfl提到的和我在这里研究:不同的端口或子域也被浏览器考虑跨域.

回答Ques2.

'Are there any changes required to do at my service end to enable this behavior?'
Run Code Online (Sandbox Code Playgroud)

是!服务器端本身需要进行更改.服务器应该响应请求

Access-Control-Allow-Origin:*

头.这里*可以用请求头本身或根据您的应用程序要求替换.如果您正在使用WCF REST服务,这里的优秀博客解释了解决方法.您需要为每个服务方法添加以下行(标题),以便在服务方法中启用CORS.

WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Origin","*"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Methods","POST"); WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Access-Control-Allow-Headers","Content-Type,Accept");

此处的规范对于在服务器/客户端上启用CORS非常有用.

回答Ques3.

JSONP主要用于GET请求,并不是最理想的用途,而是最推荐使用CORS.(我没有多探讨这个领域,但这里的Wiki和stackoverflow文章非常具有描述性).

除此之外,为了测试目的,这里一个漂亮的镀铬扩展可能会有所帮助.它可用于确保应用程序具有CORS问题.


Sen*_*l.J 5

我因模拟Ionic项目(在本地运行)与一些小型Node.JS Web服务(也在本地运行)的交互作用而导致的CORS问题苦苦挣扎了很长时间。

看一下简短的简单变通方法:Chrome的插件AllowControlAllowOrigin。

https://chrome.google.com/webstore/search/cross%20origin?utm_source=chrome-ntp-icon&_category=extensions

只需将单选按钮从红色切换为绿色,再也不会阻止请求,错误或警告!当然,这是一个临时解决方案,当停止本地测试的时机到来时,您可能必须把手放在请求标头中。同时,这是避免在那些棘手的重复性问题上浪费时间的好方法。