Olá. Tudo certo?
No post anterior, falei sobre como deixar nossos serviços operantes em domínios diferentes daquele onde estão hospedados. O que apresentei é suficiente para operações de GET e POST mas não é suficiente para operações DELETE e PUT. Nesses casos, é necessário o respeito a um protocolo diferente conhecido como CORS Preflight.
De forma simplificada, o browser identifica requests para operações DELETE e PUT e, então, envia uma espécie de solicitação para o servidor para executar esse request.
Essa solicitação ocorre através de um request com o método OPTIONS para o endereço onde será executado o request original. Esse request é, simplifcadamente, assim:
OPTIONS http://address-of-your-service.com HTTP/1.1 Access-Control-Request-Method: PUT Origin: http://request-origin.com
A API, então, deve retornar um response autorizando a operação. Algo, mais ou menos, assim:
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Allow-Methods: PUT
Em seguida, o cliente executará a operação de modificação.
Essa solicitação anterior é conhecida como CORS Preflight Request.
Agora que você já entende o conceito, sabe que suportar Preflight requests trata apenas de ter resposta apropriada para OPTIONS em seus controllers.
public HttpResponseMessage Options() { var response = new HttpResponseMessage {StatusCode = HttpStatusCode.OK}; response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE"); return response; }
Ou ainda, para evitar duplicação de código, desenvolver um DelegatingHandler.
public class CorsPreflightHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage r, CancellationToken cancellationToken ) { var request = new RequestEnvelope(r); if (!request.IsCorsPreflight) return await base.SendAsync(r, cancellationToken); var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; response.Headers.Add("Access-Control-Allow-Origin", "*"); const string supportedMethods = "POST, PUT, GET, DELETE"; response.Headers.Add("Access-Control-Allow-Methods", supportedMethods); return response; } struct RequestEnvelope { private readonly HttpRequestMessage _request; public RequestEnvelope(HttpRequestMessage request) : this() { _request = request; } public bool IsCorsPreflight { get { return ( _request.Headers.Contains("Origin") && _request.Method == HttpMethod.Options ); } } } }
Tanto o conteúdo desse post, quanto do post anterior, funcionam apenas no Internet Explorer 10 (ou mais novos).
Era isso.
Na moral Elemar tem alguma coisa que você não escreveu neste blog?
Essa semana é a 3ª vez que bato aqui procurando alguma coisa no google, hahaha
To o dia todo sofrendo com esse tal cors, vou testar esse código descrito pra ve se agora vai!
Olá Elemar. Estou tentando fazer um acesso simples cross domain, mas não consigo fazer funcionar.
Fiz todas as configurações que encontrei aqui, mas quando envio a requisição, o cabeçalho Access-Control-Allow-Origin não está lá.
Tem alguma dica pra me dar?
Meu webConfig está assim:
Minha chamada é assim:
$.ajax({
type: “GET”,
dataType: “json”,
contentType: contentType,
cache: false,
url: “http://67.205.69.111:8091/guiafacil/servicos/3.json”,
success: function (data) {
alert(“Data from Server” + JSON.stringify(data));
},
});
To perdendo um tempão com isso…