【问题标题】:CORS issue while making a http.post using Angularjs and wcf restful service使用 Angularjs 和 wcf RESTful 服务制作 http.post 时出现 CORS 问题
【发布时间】:2016-11-03 08:32:01
【问题描述】:

我是 angularjs 的新手,并尝试使用 angularjs 客户端使用 wcf restful 服务。最初我尝试了 http.get(url) 并得到了我通过将以下代码放入我想要的 wcf 服务方法中解决的 CORS 问题打电话。

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

现在,当我以与 get 相同的方式发出后调用 (http.post) 时,我得到了回复,但没有出现 CORS 问题。

但是当我尝试在发帖时传递 JSON 对象时,我再次开始遇到 CORS 问题。

我的帖子角码是:

 var requestData = {
            RequestUserName: "Abc1",
            RequestPass: "123"
        };

        var req = {
                    method: 'POST',
                    url: 'url',
                    headers: {
                        'Content-Type': 'application/json; charset=utf-8'
                    },
                    data: requestData
        };
         $http(req).success(function(){console.log("Success");
         $scope.userDetails = response.UserNameAuthenticationResult;}).error(function(){console.log("Error");});

我的 WCF 操作合约如下:

 [WebInvoke(Method="POST",UriTemplate="/Authenticate"
           ,RequestFormat=WebMessageFormat.Json
           ,ResponseFormat=WebMessageFormat.Json
           ,BodyStyle = WebMessageBodyStyle.Wrapped)]

        string UserNameAuthentication(Request request);

方法实现如下:

 public string UserNameAuthentication(Request request)
       {
         WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
       WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
      WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");

           return "true";
       }

我得到的错误如下:

**OPTIONS URL (匿名函数) @ angular.js:11442sendReq @ angular.js:11235serverRequest @ angular.js:10945processQueue @ angular.js:15552(匿名函数)@ angular.js:15568$eval @ angular.js:16820$digest @ angular.js:16636$apply @ angular.js:16928(匿名函数)@ angular.js:24551defaultHandlerWrapper @ angular.js:3398eventHandler @ angular.js:3386 localhost/:1 XMLHttpRequest 无法加载 http://localhost:8733/TestService/Login/Authenticate。响应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:14703” 使用权。响应的 HTTP 状态代码为 405。

【问题讨论】:

  • 我认为与 angularjs 无关。您需要在 wcf 应用程序中配置 CORS。 check this out.
  • 这没有帮助,我已经尝试将这段代码放在 wcf 服务的调用方法中,但仍然是同样的错误。此外,由于我已将 wcf 服务构建为类库,因此我没有添加 global.asax 文件的选项,但我们确实在 wcf 应用程序中获得了它,因此我在调用方法中添加了 Headers 代码。
  • Arjun- 我添加了插件,但没有收到上述错误,但我收到了一个新错误,上面写着 net::ERR_CONNECTION_REFUSED。
  • 考虑到我将rest服务构建为WCF服务库而不是WCF服务应用程序,如果有人可以提供示例解决方案,那将非常有帮助。

标签: .net angularjs rest wcf cors


【解决方案1】:

CORS 是浏览器和服务器设置之间的交互。

同时发布请求和响应标头会很有用。

我假设您正在与位于不同域(例如 api.example.com 而不是 www.example.com)上的 API 进行交互。由服务器设置 Access-Control-Allow-Origins 响应标头。要允许所有来源作为临时措施,请将其设置为“*”而不是空字符串,但很快您应该将其设置为您网站的实际来源,例如 www.example.com

实际上,您可能不希望它完全打开,因为这可能存在安全风险,有人可能会创建您网站的假冒版本。

同时避免 CORS 的一种简单方法是使用代理服务器。这样,所有请求都转到同一个域(html 和 API)。如果运行 Node 应用程序,您可以使用 node-http-proxy 或类似的。如果您有自定义标头或数据,这也可以避免预检请求。预检请求是您在实际请求之前在 API 上看到的 OPTIONS 请求。

以下是有关预检行为的更多信息: https://www.soasta.com/blog/options-web-performance-with-single-page-applications/

【讨论】:

  • 嗨 Derric,我已经尝试了所有可能的方法来解决这个问题,但没有运气。不确定我的 JSON 对象是否存在问题,就好像我在没有 JSON 对象的情况下发布它工作正常一样。我已经提到了我发布数据的方式。不知道这是否是正确的方式。
  • 你能从 Chrome 开发者工具中复制粘贴 HTTP 调用,然后我们可以查看标题和响应吗?具体来说,您可能会同时看到您的呼叫和使用 OPTIONS 方法的第二次呼叫。如果您无法访问 Chrome 开发工具或生产环境,还有 Fiddler 和 Moesif 等工具能够捕获 HTTP 调用以进行调试。
  • 请求 URL:localhost:8733/Design_Time_Addresses/TestService/Login/… 请求方法:OPTIONS 状态代码:405 方法不允许远程地址:[::1]:8733 响应标头视图解析 HTTP/1.1 405 方法不允许允许:POST 内容-长度:1565 内容类型:文本/html; charset=UTF-8 服务器:Microsoft-HTTPAPI/2.0 日期:2016 年 11 月 5 日星期六 13:33:10 GMT
  • Request Headers view source Accept:*/* Accept-Encoding:gzip, deflate, sdch, br Accept-Language:en-GB,en-US;q=0.8,en;q=0.6 访问-Control-Request-Headers:content-type Access-Control-Request-Method:POST Connection:keep-alive Host:localhost:8733 Origin:localhost:14703Referer:localhost:14703User-Agent:Mozilla/5.0 (Windows NT 6.1 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
【解决方案2】:

似乎没有在服务器端启用 CORS,因为不理解 OPTIONS 方法。

不妨试试这个:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE, OPTIONS");

        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}

【讨论】:

  • 由于我使用的是 WCF 服务库,我无法添加 Global.asax 文件,它可以添加到 WCF 服务应用程序中。但是,我在调用方法中添加了提到的一段代码,当我发出没有 JSON 对象的发布请求时,它解决了我的问题,但是当我使用 JSON 对象发出发布请求时出现问题。我在顶部的问题中提到了我提出发布请求的方式。
  • 您能否粘贴更新后的 HTTP 记录调用,这有助于调试。
猜你喜欢
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-23
  • 2017-07-02
  • 1970-01-01
  • 2011-09-30
  • 2016-12-28
相关资源
最近更新 更多