首页 文章

.NET Web API CORS PreFlight请求

提问于
浏览
15

我在向其他域上的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添加代码时,我只得到第一个错误 .

有人可以帮我这个吗?

4 回答

  • 4

    您可以添加处理程序来处理此类请求 .

    创建一个派生自“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);
        }
    
    }
    

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

    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
        .
        .
        .
    }
    
  • 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(在"Preflight Requests"下):

  • 0

    在我的情况下,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博客文章中找到了解决方案 .

  • 27

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

相关问题