【问题标题】:Enabling CORS between Ajax and WCF service在 Ajax 和 WCF 服务之间启用 CORS
【发布时间】:2015-11-26 16:35:41
【问题描述】:

问题

每当我尝试向我的 WCF 服务(在 IIS 上本地运行)发送 POST 请求时,我都会得到:

访问被拒绝

我的 WCF 配置(仅相关代码)

我添加了以下内容以允许使用不同的方法,并且我能够从 Request Method: 'GET' 获取信息,但不能从 POST 获取信息

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*"/>
    <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" />
    <add name="Access-Control-Allow-Methods" value="GET,POST,DELETE" />
    <add name="Access-Control-Max-Age" value="1728000" />
  </customHeaders>
</httpProtocol>

Ajax 调用

这是我的 ajax 调用,每当我尝试创建一个新的'Project'

$.ajax({
    url: baseAddress + "projects/create",
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify({
        'Title': 'Test Title',
        'Customer': {
            'Name': 'Test Name'
        }
    })
})

服务实现

这是IService.csUriTemplateMethod = 'POST'

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/projects/create")]
int CreateProject(ProjectDTO project);

额外信息

每当我通过谷歌浏览器查看标题时,我看到Request MethodOPTIONS 和响应Access-Control-Allow-Methods: GET, POST, DELETE,但我仍然无法发出POST 请求(请参阅this)。

如何在 WCF 服务中正确处理请求方法OPTIONS

编辑

好笑的是回复说:Access-Control-Allow-Methods: GET, POST, etc.,意思是既然请求问的是:Access-Control-Request-Method: POST,就应该允许发送这个请求,但是不知什么原因我得到了这个Access Denied

编辑 2

我知道Request Method: OPTIONS,但OPTIONS 询问我的服务是否允许执行POST 请求,服务回复Access-Control-Allow-Methods: GET, POST, etc. 那里说POST 允许的。

【问题讨论】:

  • “Access-Control-Allow-Headers”不应该包含“Accept, Content-Type, Origin”(缺少 Origin)吗?
  • @UncleRico 无论如何都没有任何区别:)
  • 你的标题看起来应该是这样的。您是否尝试过在项目/创建控制器中使用手动标题覆盖 [ie: Response.AppendHeader(...)] ?
  • 我不确定你的意思?能详细点吗?
  • 喜欢这里:enable-cors.org/server_aspnet.html。你能把你的 C:\Windows\System32\LogFiles\HTTPERR\httperr.log 的副本从 172.20.40.125 服务器放在这里吗?标题可能根本不是问题,而是项目/创建控制器中的一段代码。

标签: c# asp.net wcf http-headers httprequest


【解决方案1】:

它会支持OPTIONS 请求吗?根据 CORS,第一个请求将是预检请求。即 OPTIONS 验证和下一个 GET,POST 将根据 OPTIONS 响应标头成功。

更多请参考here

【讨论】:

  • 我也试过这个:&lt;add name="Access-Control-Allow-Methods" value="GET,POST,DELETE, OPTIONS" /&gt;。但没有区别。通过发送OPTIONS,它会询问“我可以发送POST吗?”由于Allow-Method 中有POST,它应该被允许,但它不是。
【解决方案2】:

我有一个 WCF 服务,需要通过 AJAX 从 JavaScript 客户端调用 - 所以我首先添加了一个带有“webHttpBinding”的端点,以允许通过纯 HTTP 访问(即没有 SOAP,如果好奇,请参阅此答案:@987654321 @)。

然后,这就是我为我的 WCF 服务启用 CORS 的方式:

  1. 添加 Global.asax 文件(如果您还没有)

  2. 实现以下方法:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        // Add CORS headers to allow a JavaScript client to call the WCF service via AJAX from a different domain
        var requestOrigin = Request.Headers.Get("Origin");
        Log.Debug($"Processing request from Origin: '{requestOrigin}'");
    
        // Accommodate for all possible cross-domain requests
        if (string.IsNullOrEmpty(requestOrigin) == false)
        {
            if (requestOrigin.Contains("devdomain"))
            {
                AddAllowedOrigin("http://devdomain");
            }
            else if (requestOrigin.Contains("qasdomain"))
            {
                AddAllowedOrigin("http://qasdomain");
            }
            else if (requestOrigin.Contains("prddomain"))
            {
                AddAllowedOrigin("http://prddomain");
            }
        }
    
        // Respond to an OPTIONS pre-flight request
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
            HttpContext.Current.Response.End();
        }
    }
    
    private static void AddAllowedOrigin(string origin)
    {
        Log.Debug($"Adding Access-Control-Allow-Origin header to response to allow Origin: '{origin}'");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
    }
    

请注意,必须将“Access-Control-Allow-Origin”标头添加到对 OPTIONS 飞行前请求以及从跨域发送的每个后续请求(例如“devdomain”等)的响应中

【讨论】:

    【解决方案3】:

    将以下行添加到 WCF 服务中的所有方法。

    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
    

    需要以下导入

    System.ServiceModel.Web;
    

    Refer this for original answer

    【讨论】:

      猜你喜欢
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 2018-07-07
      • 2018-01-31
      • 2012-12-24
      • 2011-03-02
      • 2017-07-28
      • 2014-08-18
      相关资源
      最近更新 更多