2013-05-03 10 views
8

Non sono sicuro che il problema riguardi le tecnologie coinvolte o la mia comprensione delle tecnologie.Origine non consentita da Access-Control-Allow-Origin - come abilitare CORS utilizzando un semplice stack Web e guizzo

Ho un'applicazione html5 scritta in javascript e html ospitata su un server Apache 2.2.

Ho un'applicazione java scritta in java utilizzando jetty, guice, jackson, jersey che ospita un semplice servizio REST.

Entrambe le applicazioni vengono eseguite sulla stessa macchina, uno sulla porta 80 (pura applicazione HTML5 ospitato su Apache), l'altro su 8080 (applicazione java puro ospitato sul pontile/Guice)

Credo che la risposta è nella le intestazioni mi stanno rimandando indietro. Le intestazioni CORS indicano a un browser che si consente alle applicazioni esterne di colpire la propria API. Non riesco a capire come configurare il mio server Jetty, Guice per restituire le intestazioni CORS corrette.

Sto usando un server Jetty imbastito quindi non ho un file web.xml per aggiungere le intestazioni.

Potrebbe anche essere qualcosa a che fare con come il server di applicazioni HTML5 (in questo caso apache 2.2) sta servendo l'applicazione.

Il file httpd.conf Apache ha la voce:

LoadModule headers_module modules/mod_headers.so 

<IFModule mod_headers> 
    Header add Access-Control-Allow-Origin "*" 
    Header add Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD 
    Header add Access-Control-Allow-Headers: X-PINGOTHER 
    Header add Access-Control-Max-Age: 1728000 
</IfModule> 

nella mia configurazione Guice servlet Ho il seguente:

public class RestModule extends ServletModule{ 

    @Override 
    protected void configureServlets() { 
     bind(QuestbookService.class); 

     // hook Jersey into Guice Servlet 
     bind(GuiceContainer.class); 

     // hook Jackson into Jersey as the POJO <-> JSON mapper 
     bind(JacksonJsonProvider.class).in(Scopes.SINGLETON); 

     Map<String, String> guiceContainerConfig = new HashMap<String, String>(); 
     guiceContainerConfig.put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, 
      HttpStatusCodeMetricResourceFilterFactory.class.getCanonicalName()); 
     serve("/*").with(GuiceContainer.class, guiceContainerConfig); 
    } 
} 

Credo che il problema è nel mio Guice config da quando don avere un posto dove impostare le intestazioni di risposta.

Sto utilizzando un server di jetty incorporato e quindi ho pensato che la modalità di sviluppo ignorerebbe l'intero controllo, ma potrei sbagliarmi.

Grazie per qualsiasi consiglio.

+0

possibile duplicato del [Perché vedo un ' "origine non è consentita da Access-Control-Allow-Origin" errore qui?] (http://stackoverflow.com/questions/9310112/why-am-i-seeing-an-origin-is-not-allowed-by-access-control-allow-origin-error) – Barmar

+0

La mia domanda è lato server, l'esempio riguarda il lato client. La libreria lato client si occupa già di queste incongruenze. È un problema basato sul server. – AnthonyJClink

+0

Aggiunto, dal momento che sto usando un server jetty integrato con guizzi. Non sono sicuro di come configurare senza web.xml ... So che è una mancanza di comprensione delle tecnologie. ma ritengo che lo stack tecnologico in questa domanda sia abbastanza diverso dal possibile duplicato che merita la sua attenzione poiché implica uno stack tecnologico molto diverso. – AnthonyJClink

risposta

9

Fare i requisiti specifici della mia domanda. Il server deve essere separato completamente separato dal client. Il client dovrebbe essere in grado di connettersi al server di comunicazione tramite qualsiasi metodo possibile.

Dal momento che la prima implementazione di questa applicazione sarà guidata da REST, devo essere in grado di accettare il resto da qualsiasi luogo.

Inoltre, voglio una configurazione completamente senza xml, quindi uso Guice con un server Jetty incorporato. Dal momento che non ho un file web.xml, non sono riuscito a capire come impostare le intestazioni per consentire CORS.

Dopo un sacco di tentativi ed errori, e leggendo la documentazione di guiz, ho trovato come aggiungere le intestazioni CORS alla risposta lasciando il server.

La classe Guice ServletModule consente di aggiungere filtri al contesto servlet. Questo mi consente di far passare tutte le richieste attraverso un determinato servlet.

Poiché sto cercando di creare un'applicazione di riposo che risponda alle richieste CORS, avevo bisogno di un filtro che aggiungesse le intestazioni cors alla risposta di ogni richiesta. In questo momento, risponde a tutte le richieste, ma alla fine risponderò solo se il livello di servizio risponde con un codice di risposta 200 - 300.

che le permettono di cors nella mia Guice server utilizzando incorporato ho costruito un filtro che assomiglia a questo:

@Singleton 
public class CorsFilter implements Filter{ 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain filterChain) throws IOException, ServletException { 

     if(response instanceof HttpServletResponse){ 
     HttpServletResponse alteredResponse = ((HttpServletResponse)response); 
     addCorsHeader(alteredResponse); 
    } 

    filterChain.doFilter(request, response); 
    } 

    private void addCorsHeader(HttpServletResponse response){ 
     //TODO: externalize the Allow-Origin 
     response.addHeader("Access-Control-Allow-Origin", "*"); 
     response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD"); 
     response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept"); 
     response.addHeader("Access-Control-Max-Age", "1728000"); 
    } 

    @Override 
    public void destroy() {} 

    @Override 
    public void init(FilterConfig filterConfig)throws ServletException{} 
} 

Guice fornisce una classe astratta che consente di configurare il Guice Servlet.

modulo

La configurazione è simile al seguente:

public class RestModule extends ServletModule{ 

    @Override 
    protected void configureServlets() { 
     bind(MyServiceClass.class); 

     // hook Jersey into Guice Servlet 
     bind(GuiceContainer.class); 

     // hook Jackson into Jersey as the POJO <-> JSON mapper 
     bind(JacksonJsonProvider.class).in(Scopes.SINGLETON); 

     Map<String, String> guiceContainerConfig = new HashMap<String, String>(); 

     serve("/*").with(GuiceContainer.class, guiceContainerConfig); 

     filter("/*").through(CorsFilter.class); 
    } 
} 

Ora Guice aggiungerà CORS intestazioni per ogni risposta. Permettendo alla mia pura applicazione HTML 5 di parlarci, indipendentemente da dove viene servita.

4

Basta mettere una riga nel file di codice

Response.AddHeader ("Access-Control-Allow-Origin", "*");

Sostituire * con il http://www.yoursite.com se si desidera consentire solo per particolare dominio

+0

Ho risolto questo problema utilizzando un filtro jersey – AnthonyJClink

Problemi correlati