[英]How to enable CORS in Grails 3.0.1
我想在服务器端使用 Grails 进行跨源通信。 我找到的唯一文档就是这个
https://grails.org/plugin/cors
但这是针对旧版本的 Grails。 我发现的其他文档是针对春季的:
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更容易。
具体来说,这里有一些有用的代码。 请注意,拦截器名称必须与您的控制器名称(此处为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 }
}
当我遇到CORS问题时,我正在使用emberjs框架和Grails 3.0休息应用程序。 按照本文中的步骤http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/帮助我进一步发展。
本文展示了如何使用新的Interceptor创建一个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请求正在运行。
你应该使用grails 3的新Interceptor API。 ( https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors )
您可以使用grails create-interceptor
命令grails create-interceptor
。 对于CORS拦截器,我将使用此Interceptor的after()
方法,并将其设置为匹配所有请求(或仅仅是您需要的请求)。 您可以在此方法中使用response
对象,因此设置标题应类似于Spring文档中描述的情况。
我发现的最干净,最简单的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过滤器的默认设置也可以
如果您需要为 Spring Security 核心/休息插件提供的端点启用 CORS,您必须添加以下内容:
引导程序.groovy:
SpringSecurityUtils.clientRegisterFilter("corsFilter",
SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)
资源.groovy:
beans = {
corsFilter(CorsFilter)
}
Grails 2.4.5 CORS 由于 HTTP/1.1 200 OK 在带有“OPTIONS”标头的浏览器预检请求期间标头中不存在@JeffScottBrown
@大卫廷克( https://github.com/davidtinker/grails-cors/issues/43 )
我刚刚安装了 Cors 1.1.0 插件来处理 CORS 问题,但是由于浏览器没有收到“http 状态代码 200 Ok”,我遇到了 CORS 问题。 我在 spring-security-core 插件版本方面受到限制,因为我正在开发一个旧版 Grails 2.4.5 应用程序,该应用程序需要一个 spring-security-core 版本,该版本仅适用于 nexus 中可用的 CORS 1.0.1 版本存储库。
我在我的 Grails 2.4.5 控制器中编写了一些代码来返回 200 状态代码,但是我不明白为什么 ReactJS 前端的浏览器没有得到它。
我可以从带有“curl”的命令行以及在浏览器中启动后端时看到 200 个状态代码。
$ curl -i -v -H "Authorization: Bearer token" http://localhost:5000/server-app/api/v1/user/xxx
* Trying 127.0.0.1:5000...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /server-app/api/v1/user/qatest1 HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.79.1
> Accept: */*
> Authorization: Bearer token
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=xxx; Path=/server-web; HttpOnly
Set-Cookie: JSESSIONID=xxx; Path=/server-app; HttpOnly
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Date: Wed, 12 Jan 2022 22:17:47 GMT
Date: Wed, 12 Jan 2022 22:17:47 GMT
<
{
"id": xxx,
"username": "xxx",
"firstName": "xxx",
"lastName": null,
"department":
[
"{id:xx name:xxx, description:xxx}"
]
}* Connection #0 to host localhost left intact
cors.enable.logging = true // enable logging of failed requests
cors.url.pattern = '/api/v1/*'
cors.headers = ['Access-Control-Allow-Origin': 'http://localhost:3000', // Only allow access to that origin
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET, HEAD, TRACE, OPTIONS',
]
def index(){
def users = User?.list(max:5, sort: "username", order:"asc")
response.status = 200
render(users as JSON)
}
static mappings = {
'/api/v1/users'(resources:'user')
"/api/v1/user/$username"(controller:'user', action:"findByUsername", method: 'GET')
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.