Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

problema de CORS com JAX-RS e JQuery

Boa tarde,

Eu tenho o seguinte recurso:

@POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response novoPedido(Ticket ticket) {

        ticket.getTicketItems().forEach(ticketItem -> {
            ticketItem.setTicket(ticket);
            ticketItem.getTicketItemModifiers().forEach(t -> {
                t.setTicketItem(ticketItem);
            });
        });
        ticket.setOwner(USER);
        OrderController.saveOrder(ticket, USER);

        List<KitchenTicket> kitchenTickets = KitchenTicket.fromTicket(ticket);
        kitchenTickets.forEach(kitchenTicket -> KitchenTicketDAO.getInstance().saveOrUpdate(kitchenTicket));
        TicketDAO.getInstance().saveOrUpdate(ticket);
        URI uri = URI.create("pedidos/" + ticket.getId());
        return Response.created(uri)
            .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "POST")
                .build();
    }

Eu consigo fazer um post sem problemas na url desse recurso usando o postman. Mas testando com um post no jquery eu recebo a seguinte mensagem no console:

Failed to load http://172.16.18.10:8081/api/aa/v1/pedidos: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://172.16.18.221:8080' is therefore not allowed access.

Veja a minha function:

var pedido = .........
function enviaPedido() {
    $.ajax({
                type: "POST",
                url: "http://172.16.18.10:8081/api/aa/v1/pedidos",
                data: JSON.stringify(pedido),
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                success: function(data) {
                    console.log("sucesso");
                }
                });

}

Alguém sabe me dizer o que fiz de errado ?

3 respostas
solução!

Fala Fernando, tudo bem ?

É comum isso acontecer quando não liberamos acesso aos cross origin requests vindos de web browsers.

O JAX-RS oferece uma interface (ContainerResponseFilter) que pode ser implementada para aplicar globalmente aos responses quaisquer alterações, como por exemplo, adicionar os headers necessários para ativar os CORs.

@Provider
public class CorsFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, 
      ContainerResponseContext responseContext) throws IOException {
          responseContext.getHeaders().add(
            "Access-Control-Allow-Origin", "*");
          responseContext.getHeaders().add(
            "Access-Control-Allow-Credentials", "true");
          responseContext.getHeaders().add(
           "Access-Control-Allow-Headers",
           "origin, content-type, accept, authorization");
          responseContext.getHeaders().add(
            "Access-Control-Allow-Methods", 
            "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

Com essa implementação você não deve mais ter problemas. Espero ter ajudado. Abraço!

Fonte: Baeldung Blog - http://www.baeldung.com - Post: http://www.baeldung.com/cors-in-jax-rs

A página que vc está executando o script está sendo servida pelo mesmo domínio que sua API? Se estiver, no local da URL do AJAX coloque um endereço relativo (sem a parte do domínio), pq aí não há problema de CORS, por exemplo: url: "/api/aa/v1/pedidos"

Em outras palavras, o domínio que está na barra de endereços do navegador tem que ser exatamente o mesmo domínio para o qual vc está fazendo o request do AJAX (o domínio tb inclui o número da porta e o protocolo - http ou https).

Já ví casos de usuários que estavam utilizando o editor Brackets com um servidor embutido, aí dava diferença no domínio do endereço que aparecia no navegador e o endereço do request AJAX, ocorrendo erro de CORS.

Se realmente vc estiver utilizando dois servidores com domínios diferentes, um para servir a API e outro para servir o conteúdo estático, vc deve configurar a aplicação da API para retornar os headers do CORS de maneira global. O que ocorre é que quando há um request com domínios distintos, o navegador faz um request prévio do tipo OPTIONS, e, neste request é necessário retornar os headers do CORS, é o que ele chama de "preflight".

Por isso que mesmo que vc coloque o header do CORS no request ele não funciona. Você pode confirmar isso verificando os requests que foram feitos no developer tools do navegador, é provável que vc veja o request do tipo OPTIONS e não veja o POST que vc fez via JQuery.

https://spring.io/guides/gs/rest-service-cors/

Espero ter ajudado.

Obrigado ao Rafael e ao Tiago pelo auxílio.

A dica do Rafael funcionou pra mim.

Valeu!