【问题标题】:Enable CORS for Web API 1, .net 4.0为 Web API 1、.net 4.0 启用 CORS
【发布时间】:2014-12-17 20:02:18
【问题描述】:

我需要为我的 Web API 启用 CORS,但目前无法升级到 Framework 4.5。 (我知道 System.Web.Http.Cors.EnableCorsAttribute。)

我尝试将以下内容添加到我的 Web.config 以查看它是否有效,但没有:

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*"/>
  </customHeaders>
</httpProtocol>

我还尝试使用 System.Web.Http.Filters.ActionFilterAttribute 手动将 Access-Control-Allow-Origin 标头设置为“*”(基于这篇文章:Add custom header to all responses in Web API) - 但那没有也不能解决,因为请求在进入操作过滤之前被拒绝。

所以我现在有点卡住了。感谢任何帮助。

编辑:结果

<add name="Access-Control-Allow-Origin" value="*"/>

一直是答案,我之前测试它时一定做错了什么。但是这个解决方案意味着所有操作都启用了 CORS(现在可以)。

【问题讨论】:

标签: c# asp.net-mvc asp.net-web-api cors


【解决方案1】:

POST、PUT、DELETE 等使用预飞行的 CORS。浏览器发送一个 OPTIONS 请求。这是因为浏览器首先检查服务器端是否可以使用OPTIONS 请求处理CORS,如果成功,则发送实际请求PUTPOSTDelete。由于您没有处理 OPTIONS 的操作方法,因此您会得到 405。在最简单的形式中,您必须在控制器中实现这样的操作方法。

更多解释-http://www.w3.org/TR/cors/#resource-preflight-requests

http://www.html5rocks.com/en/tutorials/cors/

public HttpResponseMessage Options()
{
    var response = new HttpResponseMessage();
    response.StatusCode = HttpStatusCode.OK;
    return response;
}

注意:此操作仅响应OPTION 请求,因此您需要向web.config 添加必要的配置,例如Access-Control-Allow-Origin = *Access-Control-Allow-Methods = POST,PUT,DELETE

Web API 2 支持 CORS,但使用 Web API 1,您必须遵循此路径。

【讨论】:

    【解决方案2】:

    也尝试添加:

        <add name="Access-Control-Allow-Headers" value="*" />
    

    【讨论】:

    【解决方案3】:

    我在 webAPI 1 中遇到了很多问题,跨域访问终于能够修复它,看看我的博客 http://keerthirb.blogspot.in/2017/08/making-cross-enable-for-webapi1.html

    交叉码是

    public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
    
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    return Task.Factory.StartNew<HttpResponseMessage>(() =>
                    {
                        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
    
                        string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                        if (accessControlRequestMethod != null)
                        {
                            response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                        }
    
                        string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                        if (!string.IsNullOrEmpty(requestedHeaders))
                        {
                            response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                        }
    
                        return response;
                    }, cancellationToken);
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
    

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    • 我同意 所以我已经包含了交叉启用代码。欲了解更多信息,用户可以转到链接。
    猜你喜欢
    • 2017-09-10
    • 2015-10-16
    • 2017-07-01
    • 2019-01-24
    • 2017-12-16
    • 2016-05-11
    • 2018-12-09
    • 2019-10-03
    • 1970-01-01
    相关资源
    最近更新 更多