如何在 Grails 3.0.1 中启用 CORS

Posted

技术标签:

【中文标题】如何在 Grails 3.0.1 中启用 CORS【英文标题】:How to enable CORS in Grails 3.0.1 【发布时间】:2015-06-17 12:20:44 【问题描述】:

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

https://grails.org/plugin/cors

但这是针对旧版本的 Grails。我发现的其他文档是针对 spring 的:

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

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

【问题讨论】:

【参考方案1】:

所以,如果你来到这里使用 grails 3.2.+,你可以使用默认方式。

转到您的application.yml 并添加:

grails:
    cors:
        enabled: true

它将添加Access-Control-Allow-Origin '*'。 如果你想要不同的东西,look this page

【讨论】:

Grails 2.5.0 的解决方案是什么?我收到from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 如果您的后端服务器和客户端正在运行 HTTP,则此方法有效。如果启用了 SSL,这已经不够了。【参考方案2】:

我们在 resources.groovy 中使用了一个普通的 servlet 过滤器来解决这个问题:

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 并没有连接过滤器。 没关系。我误解了评论。在这里使用 Grails 2.x 插件似乎对我有用:github.com/davidtinker/grails-corsThanks David!【参考方案3】:

具体来说,这里有一些有效的代码。请注意,拦截器名称必须与您的控制器名称匹配(此处为 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 

【讨论】:

【参考方案4】:

当我遇到 CORS 问题时,我正在使用 emberjs 框架和 Grails 3.0 REST 应用程序。按照本文中的步骤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://***.com/a/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 请求正在运行。

【讨论】:

【参考方案5】:

您应该使用 grails 3 的新拦截器 API。 (https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors)

您可以使用grails create-interceptor 命令创建拦截器。对于 CORS 拦截器,我将使用此拦截器的 after() 方法,并将其设置为匹配所有请求(或仅匹配您需要的请求)。您可以在该方法中使用response 对象,因此设置标头应该类似于Spring文档中描述的情况。

【讨论】:

【参考方案6】:

我发现的 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 过滤器的默认设置也可以

【讨论】:

【参考方案7】:

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

Bootstrap.groovy:

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

resources.groovy:

beans = 
    corsFilter(CorsFilter)

【讨论】:

以上是关于如何在 Grails 3.0.1 中启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

使用Grails 3配置CORS

使用 Grails 3 配置 CORS

如何在 Kitura 中测试 CORS?

如何在 Tomcat7 中部署 Grails 3.0.1 战争文件?

如何在 odata 中启用 CORS?

如何在 FastAPI 中启用 CORS?