.NET Web API CORS 预检请求

23

我在向其他域的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.
当我按照ASP.NET Web API中支持PUT和DELETE的CORS建议,在WebConfig中添加代码后,我只得到了第一个错误。请问有人能帮我吗?
4个回答

37

您可以添加一个处理程序来处理此类请求。

创建一个继承自“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
    .
    .
    .
}

3
有趣的是,这个处理程序在来自Chrome的请求上不会被调用。O_o - Brandon
1
在响应头中添加 'response.Headers.Add("Access-Control-Allow-Credentials", "true");' 后,它对我来说运行良好。 - Inaam ur Rehman

5
您正在进行的AJAX调用到Web API触发了一个Preflight检查(HTTP动词“OPTIONS”)。否则,您将收到405错误,因此需要由您的系统处理。有一些关于如何处理这个问题的答案在SO上,例如: 处理CORS Preflight请求到ASP.NET MVC操作 如果您遵循以下准则,也可以完全避免此预检调用。
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("预检请求"章节):


2
在我的情况下,对于具有自定义标头的XHR请求,CORS无法正常工作(因为它需要预检查OPTIONS请求)。 我根据官方文档的描述配置了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可以处理它。
我在这篇博客文章中找到了解决方案。

0

我在使用Firefox和Chrome浏览器进行GET请求时遇到了预检问题(404错误),实际上转换为OPTIONS请求。经过数小时的研究,我发现如果我们从AJAX调用中删除Content-type参数,我们就可以从服务器获取数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接