【问题标题】:How to enable CORS in Grails 3.0.1如何在 Grails 3.0.1 中启用 CORS
【发布时间】: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

【问题讨论】:

    标签: grails cors grails-3.0


    【解决方案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://stackoverflow.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)
            }
            

            【讨论】:

              猜你喜欢
              • 2015-06-13
              • 2015-07-26
              • 2015-06-13
              • 2015-08-20
              • 2014-07-29
              • 2015-05-27
              • 2020-11-24
              • 2018-10-19
              • 2021-04-14
              相关资源
              最近更新 更多