2015-04-11 12 views
11

Mi piacerebbe fare comunicazioni di origine incrociata usando Grails sul lato server. L'unica documentazione che ho trovato è questaCome abilitare CORS in Grails 3.0.1

https://grails.org/plugin/cors

, ma questo è per una vecchia versione di Grails. L'altra documentazione che ho trovato è per la primavera:

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

così ho aggiunto il file nella cartella SimpleCorsFilter.groovyinit/myproject/, ma non so come collegare questa componente in resources.groovy

risposta

7

Per essere precisi, ecco un codice che funziona. Si noti il ​​nome intercettore deve corrispondere al nome del controller (qui, workRequest), il dominio deve essere quello che sta chiamando (qui, localhost: 8081) ed è il metodo prima() che si desidera:

package rest 
class WorkRequestInterceptor { 
boolean before() { 
    header("Access-Control-Allow-Origin", "http://localhost:8081") 
    header("Access-Control-Allow-Credentials", "true") 
    header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE") 
    header("Access-Control-Max-Age", "3600") 
    true 
} 

boolean after() { true } 
} 
2

Si dovrebbe usare graal La nuova API Interceptor di 3. (https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors)

È possibile creare un intercettore con il comando grails create-interceptor. Per un intercettore CORS, userei il metodo after() di questo Intercettatore e lo configurerò per soddisfare tutte le richieste (o solo le richieste di cui hai bisogno). È possibile utilizzare l'oggetto response in questo metodo, pertanto l'impostazione delle intestazioni dovrebbe essere simile al caso descritto nella documentazione Spring.

11

abbiamo usato un filtro servlet normale con una voce in resources.groovy per risolvere questo problema:

public class CorsFilter extends OncePerRequestFilter { 

    @Override 
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) 
      throws ServletException, IOException { 

     String origin = req.getHeader("Origin"); 

     boolean options = "OPTIONS".equals(req.getMethod()); 
     if (options) { 
      if (origin == null) return; 
      resp.addHeader("Access-Control-Allow-Headers", "origin, authorization, accept, content-type, x-requested-with"); 
      resp.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS"); 
      resp.addHeader("Access-Control-Max-Age", "3600"); 
     } 

     resp.addHeader("Access-Control-Allow-Origin", origin == null ? "*" : origin); 
     resp.addHeader("Access-Control-Allow-Credentials", "true"); 

     if (!options) chain.doFilter(req, resp); 
    } 
} 

resources.groovy:

beans = { 
    corsFilter(CorsFilter) 
} 

questo funziona con le richieste CORS utilizzando authenticatio base n. Ho scritto il plugin Grails 2.x e questo mi è sembrato più semplice che farlo funzionare con Grails 3.

+0

Questo non sembra funzionare per me. Sto usando Grails 2.5.4 e la creazione della classe 'CorsFilter' in src/groovy e quindi la definizione del bean in ** resources.groovy ** non ha collegato il filtro. –

+0

Non importa. Ho frainteso il commento. L'uso del plugin Grails 2.x qui sembra funzionare per me: https://github.com/davidtinker/grails-cors Grazie David! –

5

Stavo giocando con il framework emberjs insieme a un'applicazione di riposo Grails 3.0 quando sono stato colpito dal problema CORS. Seguendo i passaggi in questo articolo http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/ mi ha aiutato ad andare oltre.

L'articolo mostra come utilizzare i nuovi Interceptor per creare una classe CorsInterceptor che imposta le intestazioni corrette.

Questo ha funzionato come previsto per le richieste GET, ma non è riuscito per le richieste POST e PUT. Il motivo per questo era che una richiesta di preflight OPZIONI è stata inviata prima a http://localhost:8080/mycontroller/1234, che nel mio caso ha causato un 404 non trovato da restituire.

Con l'aiuto di questa risposta https://stackoverflow.com/a/31834551 ho modificato la classe CorsInterceptor a questo, invece:

class CorsInterceptor { 

    CorsInterceptor() { 
    matchAll() 
    } 

    boolean before() { 
    header("Access-Control-Allow-Origin", "http://localhost:4200") 
    boolean options = ("OPTIONS" == request.method) 
    if (options) { 

     header("Access-Control-Allow-Origin", "http://localhost:4200") 
     header("Access-Control-Allow-Credentials", "true") 
     header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE") 
     header("Access-Control-Max-Age", "3600") 

     response.status = 200 
    } 

    true 
    } 

    boolean after() { true } 

} 

Ora POST e PUT richieste stavano lavorando.

1

La soluzione più semplice e pulita per i graal 3.1.x che ho trovato è di aggiungere la CorsFilter default di Apache:

import org.apache.catalina.filters.CorsFilter 

// Place your Spring DSL code here 
beans = { 
    corsFilter(CorsFilter) //Custom CorsFilter under src/main/java/ works as well. I prefer Apache though... 
} 

La risposta # user215556 funziona così, ma l'impostazione di default del filtro Apache Cors è giusta pure

10

Quindi, se si ottiene qui utilizzando Grails 3.2. + è possibile utilizzare il modo predefinito.

Vai al tuo application.yml e aggiungere:

grails: 
    cors: 
     enabled: true 

Si aggiungerà Access-Control-Allow-Origin '*'. Se vuoi qualcosa di diverso,

+0

Per Grails 3.2+ questa è la soluzione giusta. –

Problemi correlati