如何在 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的主要内容,如果未能解决你的问题,请参考以下文章