如何在Grails 3.0.1中启用CORS

20

我想在服务器端使用Grails进行跨域通信。我找到的唯一文档是:

https://grails.org/plugin/cors

但这是针对旧版本的Grails。我找到的其他文档是关于Spring的:

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

因此,我将文件SimpleCorsFilter.groovy添加到init/myproject/文件夹中,但我不知道如何将此组件连接到resources.groovy

7个回答

27

所以,如果您使用的是Grails 3.2.+,则可以使用默认方式。

前往您的application.yml并添加:

grails:
    cors:
        enabled: true

它将添加Access-Control-Allow-Origin '*'。 如果你想要其他设置,请查看这个页面


如果您的后端服务器和客户端正在运行HTTP,则此方法有效。但是,如果启用了SSL,则这已经不再足够。 - beechovsky

12

我们使用了一个普通的Servlet过滤器,并在resources.groovy中添加了一个条目来解决这个问题:

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

这适用于使用基本身份验证的CORS请求。我编写了Grails 2.x插件,这似乎比让它与Grails 3一起使用更容易。


这对我似乎没有起作用。我正在使用Grails 2.5.4,在src/groovy中创建CorsFilter类,然后在resources.groovy中定义bean并没有连接过滤器。 - Marty Chang
没关系。我误解了评论。在这里使用Grails 2.x插件似乎对我有用:https://github.com/davidtinker/grails-cors 谢谢David! - Marty Chang

9

具体来说,以下是一些可行的代码。请注意,拦截器名称必须与您的控制器名称匹配(这里是workRequest),域名需要是您正在调用的任何内容(这里是localhost:8081),并且您需要使用before()方法:

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

6
我在使用EmberJS框架和Grails 3.0 REST应用程序时遇到了CORS问题。按照这篇文章http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/中的步骤帮助我进一步解决了这个问题。
该文章展示了如何使用新的拦截器来创建CorsInterceptor类,以设置正确的标头。
class CorsInterceptor {

  CorsInterceptor() {
    matchAll()
  }

  boolean before() {
    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" )
    true
  }

  boolean after() { true }
}

这对于GET请求按预期工作,但对于POST和PUT请求失败了。原因是首先发送了一个OPTIONS预检请求到http://localhost:8080/mycontroller/1234,在我的情况下导致返回404未找到
在这个答案https://dev59.com/_lwZ5IYBdhLWcg3wTOvr#31834551的帮助下,我将CorsInterceptor类修改为以下内容:
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 }

}

现在POST和PUT请求已经可以正常工作。

3

我发现Grails 3.1.x最干净、最简单的解决方案是添加Apache默认的CorsFilter:

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

#user215556的回答也可以,但Apache Cors过滤器的默认设置也是可以的。


3
你应该使用Grails 3的新拦截器API。你可以使用 grails create-interceptor 命令创建一个拦截器。对于CORS拦截器,我建议使用这个拦截器的after()方法,并设置它匹配所有请求(或只是您需要的请求)。在此方法中,您可以使用response对象,因此设置标题应类似于Spring文档中描述的情况。详情请参见https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors

0
如果您需要为Spring Security核心/REST插件提供的端点启用CORS,则必须添加以下内容:

Bootstrap.groovy:

SpringSecurityUtils.clientRegisterFilter("corsFilter",
    SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)

resources.groovy:

beans = {
    corsFilter(CorsFilter)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接