.NET Web API CORS 预检请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20792950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:35:31  来源:igfitidea点击:

.NET Web API CORS PreFlight Request

.netcorshttp-deletepreflight

提问by MilanG

I have some trouble make PUT and DELETE CORS request to Web API on other domain.

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

I've coded API by tutorial http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#create-webapi-project.

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

GET and POST Requests works fine, but DELETE and PUT doesn't. I get this message:

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.

When I add code to WebConfig suggested on CORS support for PUT and DELETE with ASP.NET Web API, I get only first error.

当我向使用 ASP.NET Web API 的 CORS 支持 PUT 和 DELETE建议的 WebConfig 添加代码时,我只收到第一个错误。

Can anyone help me with this please?

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

回答by MCurbelo

You can add a handler to deal with this type of request.

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

Create a class derive from "DelegatingHandler":

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

}

Later in WebApiconfig.cs in Register method add this:

稍后在 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
    .
    .
    .
}

回答by Dominik

The AJAX call you're doing to the Web API is triggering a Preflight check (HTTP verb "OPTIONS"). This needs to be handled by your system otherwise you'll get the 405 error. There are a few answers on how to do that here on SO, like:

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

Handling CORS Preflight requests to ASP.NET MVC actions

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

You can also avoid this preflight call altogether if you follow the following guidelines.

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

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

Taken from http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api(under "Preflight Requests"):

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

回答by Mariusz Pawelski

In my case CORS wasn't working for XHR requests with custom header (because it requires preflight OPTIONS request). I configured CORS as described in official documentation

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

Solution was to add this to web.config

解决方案是将此添加到 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>

Without this configuration the IIS will intercept OPTION requests and after adding this config ASP.NET can handle it.

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

I found the solution on thisblog post.

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

回答by Hiren Parekh

I was facing a preflight issue(404 error) on GET request with firefox & chrome browsers which actually converted to OPTIONS request,after spending hours I found that if we remove the Content-type parameter from AJAX call we can get the data from server.

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