09 Aplicação Web com VRaptor 4 – Resolvendo um problema com CORS

Olá Pessoal tudo em cima? Esse será um post bem rapidinho, vamos arrumar o CORS do nosso servidor. Já já explico o que é esse tal de CORS, como arrumar etc. Mas antes aqueles recadinhos!

Já estamos trabalhando no nosso projeto, caso tenha caído neste tutorial acidentalmente, pode ver a lista dos episódios anteriores na introdução que fiz para estes posts. E sempre lembre, você pode e deve acompanhar os códigos pelo meu github, segue o link ai em baixo:

https://github.com/pedro-hos/aprendendo-vraptor

Cross-origin resource sharing (CORS)(ou compartilhamento de recursos cross-origem) é uma especificação de uma tecnologia de navegadores que define meios para um servidor permitir que seus recursos sejam acessados por uma página web de um domínio diferente. Esse tipo de acesso seria de outra forma negado pela same origin policy. CORS define um meio pelo qual um navegador e um servidor web podem interagir para determinar se deve ou não requisições cross-origem. ¹

Agora que sabemos que com o CORS ativo, conseguimos fazer requisições de domínios diferentes, vamos ativá-los.

Primeiro vamos criar a classe CORSController dentro do mesmo pacote dos outros Controllers. Em seguida vamos colocar o código abaixo dentro da Classe.

package br.com.pedroHos.controller;

import java.util.Set;

import javax.enterprise.event.Observes;
import javax.inject.Inject;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Options;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.controller.HttpMethod;
import br.com.caelum.vraptor.events.VRaptorRequestStarted;
import br.com.caelum.vraptor.http.route.Router;
import br.com.caelum.vraptor.view.Results;

@Controller
public class CORSController {
    
    private Result result;
    private Router router;

    /**
     * @deprecated
     */
    public CORSController() { }

    @Inject
    public CORSController(Result result, Router router) {
        this.result = result;
        this.router = router;
    }

    @Options
    @Path(value = "/*")
    public void options(@Observes VRaptorRequestStarted requestInfo) {
            
        Set<HttpMethod> allowed = router.allowedMethodsFor(requestInfo.getRequest().getRequestedUri());
        String allowMethods = allowed.toString().replaceAll("\\[|\\]", "");
        
        result.use(Results.status()).header("Allow", allowMethods);
        result.use(Results.status()).header("Access-Control-Allow-Methods", allowMethods);
        result.use(Results.status()).header("Access-Control-Allow-Headers", "Content-Type, X-Requested-With, accept, Authorization, origin");
    }

}

Pronto, agora o próximo passo é criar um Interceptador, para interceptar nossas requisições, certo? Para isso cria a classe CORSInterceptor, dentro do pacote br.com.pedroHos.controller.interceptor; E vamos anotá-la com @Intercepts, em seguida cole o código a seguir na classe:

package br.com.pedroHos.controller.interceptor;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.caelum.vraptor.BeforeCall;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;

@Intercepts
public class CORSInterceptor {
    
    private HttpServletRequest request;
    private HttpServletResponse response;

    /**
     * @deprecated
     */
    public CORSInterceptor() {}

    @Inject
    public CORSInterceptor(    HttpServletRequest request,
                            HttpServletResponse response ) {
        this.request = request;
        this.response = response;
    }

    @BeforeCall
    public void intercept() throws InterceptionException {
        
        String origin = request.getHeader("origin") != null ? request.getHeader("origin") : "*";
        
        response.addHeader("Access-Control-Allow-Origin", origin);
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.addHeader("Access-Control-Expose-Headers", "Content-Type, Location");
    }

}

Pronto, bem fácil heim, agora sim, podemos começar a trabalhar com a view. Faltava esse detalhe, mas agora já está tudo certo 😀

Anúncios

5 comentários

  1. Pingback: Aplicação Web com VRaptor 4 – Introdução | Pedro Hos
  2. VictorHVS · junho 4, 2015

    Olá amigo, infelizmente ainda estou enfrentando este problema:/

    Inclusive fiz isso:

    var settings = {
    “async”: true,
    “crossDomain”: true,
    “url”: “http://pediatrics-victorhvs.rhcloud.com/api/pacientes”,
    “method”: “GET”,
    “headers”: {
    “Access-Control-Allow-Headers”:”*”,
    “nome”: “Victor Hugo”,
    “email”: “vhv.sousa@gmail.com”
    }
    }

    $.ajax(settings).done(function (response) {
    console.log(response);
    });

    Fiz como sugerido, ele começa a frescar com meus outros headers… saquem só:

    XMLHttpRequest cannot load http://pediatrics-victorhvs.rhcloud.com/api/pacientes. Request header field nome is not allowed by Access-Control-Allow-Headers.

    • Pedro Henrique de Oliveira Silva · junho 8, 2015

      Victor. VC fez as classes de core? Para ele aceitar requisição de fora?

  3. Vargthon Nunes · dezembro 22, 2015

    Olá Pedro,
    Gostaria de tirar uma dúvida com você.
    Estou fazendo a aplicação do seu blog, porém percebi que depois de fazer a classe do CORS e o interceptador, JSP parou de funcionar. Isso é normal?

    • Pedro Henrique de Oliveira Silva · dezembro 22, 2015

      Acho q não era para parar não. Teria q ver o que aconteceu

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s