我想在服务器端使用Grails进行跨域通信。我找到的唯一文档是:
https://grails.org/plugin/cors
但这是针对旧版本的Grails。我找到的其他文档是关于Spring的:
https://spring.io/guides/gs/rest-service-cors/
因此,我将文件SimpleCorsFilter.groovy
添加到init/myproject/
文件夹中,但我不知道如何将此组件连接到resources.groovy
。
我想在服务器端使用Grails进行跨域通信。我找到的唯一文档是:
https://grails.org/plugin/cors
但这是针对旧版本的Grails。我找到的其他文档是关于Spring的:
https://spring.io/guides/gs/rest-service-cors/
因此,我将文件SimpleCorsFilter.groovy
添加到init/myproject/
文件夹中,但我不知道如何将此组件连接到resources.groovy
。
所以,如果您使用的是Grails 3.2.+,则可以使用默认方式。
前往您的application.yml
并添加:
grails:
cors:
enabled: true
它将添加Access-Control-Allow-Origin '*'
。
如果你想要其他设置,请查看这个页面
我们使用了一个普通的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一起使用更容易。
CorsFilter
类,然后在resources.groovy中定义bean并没有连接过滤器。 - Marty Chang具体来说,以下是一些可行的代码。请注意,拦截器名称必须与您的控制器名称匹配(这里是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 }
}
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 }
}
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 }
}
我发现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过滤器的默认设置也是可以的。
grails create-interceptor
命令创建一个拦截器。对于CORS拦截器,我建议使用这个拦截器的after()
方法,并设置它匹配所有请求(或只是您需要的请求)。在此方法中,您可以使用response
对象,因此设置标题应类似于Spring文档中描述的情况。详情请参见https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors。Bootstrap.groovy:
SpringSecurityUtils.clientRegisterFilter("corsFilter",
SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)
resources.groovy:
beans = {
corsFilter(CorsFilter)
}