22

我在向其他域上的 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 的 CORS 支持 PUT 和 DELETE建议的 WebConfig 添加代码时,我只收到第一个错误。

任何人都可以帮我解决这个问题吗?

4

4 回答 4

35

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

创建一个派生自“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
    .
    .
    .
}
于 2015-01-28T14:47:54.900 回答
5

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

处理对 ASP.NET MVC 操作的 CORS 预检请求

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

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(在“预检请求”下):

于 2014-01-23T21:03:27.993 回答
2

在我的情况下,CORS 不适用于带有自定义标头的 XHR 请求(因为它需要预检 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 可以处理它。

我在这篇博文中找到了解决方案。

于 2016-06-22T08:53:36.473 回答
0

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

于 2015-06-09T14:27:34.843 回答