【问题标题】:.NET Web API CORS PreFlight Request.NET Web API CORS PreFlight 请求
【发布时间】:2014-01-14 14:07:33
【问题描述】:

我在向其他域上的 Web API 发出 PUT 和 DELETE CORS 请求时遇到了一些麻烦。

我已经通过教程http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#create-webapi-project 编写了 API。

GET 和 POST 请求工作正常,但 DELETE 和 PUT 不能。我收到这条消息:

Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource.

当我向 CORS support for PUT and DELETE with ASP.NET Web API 建议的 WebConfig 添加代码时,我只收到第一个错误。

谁能帮我解决这个问题?

【问题讨论】:

    标签: .net cors http-delete preflight


    【解决方案1】:

    您可以添加一个处理程序来处理这种类型的请求。

    创建一个派生自“DelegatingHandler”的类:

    public class PreflightRequestsHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.Headers.Contains("Origin") && request.Method.Method.Equals("OPTIONS"))
            {
                var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
                // Define and add values to variables: origins, headers, methods (can be global)               
                response.Headers.Add("Access-Control-Allow-Origin", origins);
                response.Headers.Add("Access-Control-Allow-Headers", headers);
                response.Headers.Add("Access-Control-Allow-Methods", methods);
                var tsc = new TaskCompletionSource<HttpResponseMessage>();
                tsc.SetResult(response);
                return tsc.Task;
            }
            return base.SendAsync(request, cancellationToken);
        }
    
    }
    

    稍后在 WebApiconfig.cs 的 Register 方法中添加:

    public static void Register(HttpConfiguration config)
    {
        // Define and add values to variables: origins, headers, methods (can be global) 
        // Enable global CORS
        config.EnableCors(new EnableCorsAttribute(origins, headers, methods));
    
        // Add handler to deal with preflight requests, this is the important part
        config.MessageHandlers.Add(new PreflightRequestsHandler()); // Defined above
        .
        .
        .
    }
    

    【讨论】:

    • 有趣的是,这个处理程序不会被来自 Chrome 的请求调用。 O_o
    • 在响应标头中添加 'response.Headers.Add("Access-Control-Allow-Credentials", "true");' 后,对我来说效果很好
    【解决方案2】:

    您对 Web API 执行的 AJAX 调用正在触发预检检查(HTTP 动词“OPTIONS”)。这需要由您的系统处理,否则您将收到 405 错误。关于如何在 SO 上执行此操作有一些答案,例如:

    Handling CORS Preflight requests to ASP.NET MVC actions

    如果您遵循以下准则,您也可以完全避免此预检调用。

    The browser can skip the preflight request if the following conditions are true:
    
    The request method is GET, HEAD, or POST, **and**
    The application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, **and**
    The Content-Type header (if set) is one of the following:
     - application/x-www-form-urlencoded
     - multipart/form-data
     - text/plain
    

    取自http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api(在“预检请求”下):

    【讨论】:

      【解决方案3】:

      在我的情况下,CORS 不适用于带有自定义标头的 XHR 请求(因为它需要预检 OPTIONS 请求)。我按照official documentation中的描述配置了CORS

      解决方案是将其添加到web.config

      <system.webServer>
        <handlers>
          <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
          <remove name="OPTIONSVerbHandler" />
          <remove name="TRACEVerbHandler" />
          <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        </handlers>
      </system.webServer>
      

      如果没有此配置,IIS 将拦截 OPTION 请求,添加此配置后 ASP.NET 可以处理它。

      我在this 博文上找到了解决方案。

      【讨论】:

        【解决方案4】:

        我在使用 firefox 和 chrome 浏览器的 GET 请求时遇到了预检问题(404 错误),实际上转换为 OPTIONS 请求,花了几个小时后我发现如果我们从 AJAX 调用中删除 Content-type 参数,我们可以获取数据来自服务器。

        【讨论】:

          猜你喜欢
          • 2015-01-14
          • 2018-07-03
          • 2019-01-05
          • 2014-04-25
          • 2020-06-30
          • 2020-05-06
          • 2016-06-10
          • 1970-01-01
          • 2012-12-22
          相关资源
          最近更新 更多