2012-04-03 14 views
5

sto cercando di impostare il supporto CORS in Grails, e sto usando il seguente filtro:CORS in grails - Tutte le richieste falliscono?

class CorsFilters { 
    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       response.setHeader("Access-Control-Allow-Origin", "*") 
      } 
     } 
    } 
} 

Da test, sembra che l'header di risposta è impostata correttamente per tutte le richieste, ma quando faccio una richiesta esternamente contro localhost o qualche server disponibile a me, ottengo il seguente errore:

XMLHttpRequest cannot load http://server:8080. Origin http://jsbin.com is not allowed by Access-Control-Allow-Origin. 

This live example opere nel mio caso di Chrome, quindi non so che cosa potrebbe accadere qui. Nelle richieste che non riescono, sto provando a colpire direttamente tomcat.

Cosa potrebbe accadere perché questo fallisca?

+0

Due cose vengono in mente. 1. L'utilizzo di localhost (un dominio di primo livello) non è una buona idea; Non riesco a trovare la fonte in questo momento, ma ho avuto problemi non molto tempo fa con questo. Usa il tuo file hosts per configurare un host falso. 2. Il codice in JSBin è effettivamente quello che stai utilizzando per la richiesta? In caso contrario, alcune librerie/framework JS potrebbero inviare prima una richiesta OPTIONS (pre-flight), che è necessario rispondere in modo appropriato. Conferma se questo è il caso e posso fornire una risposta, ho già sviluppato una soluzione in Grails. In bocca al lupo! – Esteban

risposta

2

Sembra che i filtri Grails, per impostazione predefinita, siano in funzione troppo tardi nella catena del filtro.

Se si genera il modello web.xml e si aggiunge un filtro sotto sitemesh, questo funziona.

<filter> 
    <filter-name>CORSFilter</filter-name> 
    <filter-class>com.blah.CorsFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>CORSFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

e

class CorsFilter implements Filter { 
    public void init(FilterConfig fConfig) throws ServletException { } 

    public void destroy() { } 

    public void doFilter(
      ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException { 

     ((HttpServletResponse) response).addHeader(
       "Access-Control-Allow-Origin", "*" 
     ) 
     chain.doFilter(request, response) 
    } 
} 
+7

Ho scritto un plugin Grails per fare questo: http://grails.org/plugin/cors –

+2

Basta modificare BuildConfig.groovy: plugins {runtime ": cors: 1.0.0" ... } –

0

Access-Control-Allow-Origin dovrebbe contenere il nome di dominio esatto (btw, per alcuni browser '*' funziona anche), jsbin.com nel tuo caso.

+0

Un jolly, '*' è anche un valore perfettamente valido - si veda [\ [spec \]] (http://www.w3.org/TR/cors/#http-access-control-allow-origin). –

+0

Sì, lo so. Ma i browser non si preoccupano delle specifiche –

1

È possibile impostare l'origine in modo dinamico. Raccomando anche di aggiungere l'intero set di intestazioni quando si applica.

response.setHeader('Access-Control-Allow-Origin', request.getHeader("Origin")) 
response.setHeader('Access-Control-Allow-Methods', 'POST, PUT, GET, OPTIONS, PATCH') 
response.setHeader('Access-Control-Allow-Headers', 'X-Additional-Headers-Example') 
response.setHeader('Access-Control-Allow-Credentials', 'true') 
response.setHeader('Access-Control-Max-Age', '1728000') 
+0

Perché è buono o necessario? –

Problemi correlati