从angularjs

时间:2015-07-24 14:18:45

标签: javascript angularjs wcf rest cors

我正在学习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>

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;});            
});

奇怪的行为是这段代码在IE11中运行得非常好,但它并没有在Chrome / Firefox中运行。

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

  

{&#34;数据&#34;:空,&#34;状态&#34;:0,&#34;配置&#34; {&#34;方法&#34;:&#34; GET& #34;&#34; transformRequest&#34;:[空],&#34; transformResponse&#34;:[空],&#34; URL&#34;:&#34; http://localhost:70/DocumentRESTService.svc/GetDocuments/&# 34;,&#34;头&#34; {&#34;接受&#34;:&#34;应用/ JSON,   text / plain, / &#34;}},&#34; statusText&#34;:&#34;&#34;}

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

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

XMLHttpRequest无法加载http://localhost:70/DocumentRESTService.svc/GetDocuments/。 No&#39; Access-Control-Allow-Origin&#39;标头出现在请求的资源上。 Origin&#39; file://&#39;因此不允许访问。

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

XMLHttpRequest无法加载http://localhost:70/DocumentRESTService.svc/GetDocuments/。 No&#39; Access-Control-Allow-Origin&#39;标头出现在请求的资源上。起源&#39; http://127.0.0.1:55969&#39;因此不允许访问。

  • [Firefox控制台:]

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

这里的问题很少:

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

    P.S:

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

4 个答案:

答案 0 :(得分:7)

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

回答 Ques1。

'Why is localhost or my machineName considered to be a cross-domain request?'

正如@charlietfl提到的并且我研究了here:不同的端口或子域也被浏览器考虑跨域。

回答 Ques2。

'Are there any changes required to do at my service end to enable this behavior?'

YES!服务器端本身需要进行更改。服务器应该使用

响应请求
  

Access-Control-Allow-Origin:*

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

  

WebOperationContext.Current.OutgoingResponse.Headers.Add(
  &#34; Access-Control-Allow-Origin&#34;,&#34; *&#34;);   WebOperationContext.Current.OutgoingResponse.Headers.Add(
  &#34;访问控制 - 允许 - 方法&#34;,&#34; POST&#34;);   WebOperationContext.Current.OutgoingResponse.Headers.Add(
  &#34;访问控制允许标题&#34;,&#34;内容类型,接受&#34;);

规范here对于在服务器/客户端上启用CORS非常有用。

回答Ques3。

JSONP主要用于GET请求,并不是最合适的用途,而是最推荐使用CORS。 (我还没有多探索这个领域,但Wiki&amp; stackoverflow文章here非常具有描述性。

除此之外,出于测试目的,一个漂亮的铬extension here可能会有所帮助。它可以用来确保应用程序有CORS问题。

答案 1 :(得分:4)

由于模拟的Ionic项目(本地运行)与一些小型Node.JS Web服务(也在本地运行)的交互引起的CORS问题,我挣扎了太长时间。

看看简单易用的解决方法:Chrome的插件AllowControlAllowOrigin。

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

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

答案 2 :(得分:1)

如果您在访问在localhost机器上运行的REST API时遇到AngularJS应用程序中的CORS问题,请检查以下内容:在服务器应用程序中添加CORS过滤器。就我而言,我在Spring应用程序中添加了以下代码

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}

}

在angularjs代码中,不要像http:// localhost :8080 /../那样提供网址。而不是localhost提供您的主机IP号。

它会正常工作

答案 3 :(得分:0)

我的朋友。 只输入

/DocumentRESTService.svc/GetDocuments