2012-04-03 15 views
5

Estoy intentando fijar el apoyo CORS en griales, y estoy usando el siguiente filtro:CORS in grails: ¿fallan todas las solicitudes?

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

De las pruebas, parece que la cabecera de respuesta está configurado correctamente para todas las solicitudes, pero cuando hago una solicitud externamente contra localhost o algún servidor disponible para mí, me sale el siguiente error:

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

This live example trabajos en mi instancia de Chrome, así que no sé lo que podría estar sucediendo aquí. En las solicitudes que fallan, trato de atacar a tomcat directamente.

¿Qué podría estar pasando para que esto falle?

+0

Dos cosas vienen a la mente. 1. Usar localhost (un dominio de primer nivel) no es una buena idea; No puedo encontrar la fuente en este momento, pero tuve problemas no hace mucho con esto. Usa tu archivo de hosts para configurar un host falso. 2. ¿El código en JSBin es realmente lo que estás usando para la solicitud? De lo contrario, algunas bibliotecas/frameworks JS pueden enviar primero una solicitud OPTIONS (pre-flighted), que debe responder de manera adecuada. Confirme si este es el caso y puedo dar una respuesta. Ya he desarrollado una solución en Grails. ¡Buena suerte! – Esteban

Respuesta

2

Parece que los filtros Grails, por defecto, se ejecutan demasiado tarde en la cadena de filtros para ser utilizados.

Si genera la plantilla web.xml y agrega un filtro debajo de sitemesh, esto funciona.

<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> 

y

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

Escribí un plugin de Grails para hacer esto: http://grails.org/plugin/cors –

+2

Simplemente edite BuildConfig.groovy: plugins {runtime ": cors: 1.0.0" ... } –

0

Access-Control-Allow-Origin debe contener el nombre de dominio exacto (por cierto, en algunos navegadores '*' funciona tan bien), jsbin.com en su caso.

+0

Un comodín, '*' también es un valor perfectamente válido; consulte [\ [spec \]] (http://www.w3.org/TR/cors/#http-access-control-allow-origin). –

+0

Sí, lo sé. Pero los navegadores no se preocupan por las especificaciones –

1

Puede establecer el origen de forma dinámica. También recomiendo agregar todo el conjunto de encabezados cuando corresponda.

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

¿Por qué es esto bueno o necesario? –

Cuestiones relacionadas