Вопрос

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

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

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

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.

Can anyone help me with this please?

Это было полезно?

Решение

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

Create a class derive from "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:

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
    .
    .
    .
}

Другие советы

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:

Handling CORS Preflight requests to ASP.NET MVC actions

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"):

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

Solution was to add this to 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.

I found the solution on this blog post.

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top