【问题标题】:How to enable cross-origin requests in Grails websocket plugin如何在 Grails websocket 插件中启用跨域请求
【发布时间】:2015-09-02 15:58:38
【问题描述】:

我尝试为 Grails 覆盖 spring websocket plugin 的默认配置,如下所示:

@Configuration
@EnableWebSocketMessageBroker
class CorsWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    void configureMessageBroker(MessageBrokerRegistry messageBrokerRegistry) {
        messageBrokerRegistry.enableSimpleBroker "/queue", "/topic"
        messageBrokerRegistry.setApplicationDestinationPrefixes "/app"
    }

    @Override
    void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        StompWebSocketEndpointRegistration registration = stompEndpointRegistry.addEndpoint("/stomp")
        registration.setAllowedOrigins('http://localhost', 'http://localhost:8080')
        registration.withSockJS().setSupressCors(false)
    }

   // [...]
}

我也尝试过执行 .setAllowedOrigins('*'),但它仍然无法正常工作。

但是,当我注册我的客户端时,“Access-Control-Allow-Origin”标头从未在 /stomp/info 端点上设置。我总是得到“XMLHttpRequest 无法加载 http://localhost:8080/app/stomp/info。请求的资源上没有 'Access-Control-Allow-Origin' 标头。因此不允许访问 Origin 'http://localhost'。”

【问题讨论】:

  • 您是否将该配置类定义为 bean?例如我将它添加到插件自述文件中提到的resources.groovy?除此之外,cors 默认是启用的(所以不需要 setSuppressCors(false))。
  • 是的,我做到了。我将 CorsWebSocketConfig.groovy 文件放在 src/groovy/my/package 文件夹中,并在 resources.groovy 中定义了一个 bean 作为 webSocketConfig my.package.CorsWebSocketConfig

标签: grails grails-plugin spring-websocket


【解决方案1】:

我使用来自https://github.com/davidtinker/grails-cors 的信息解决了这个问题。 Grails-cors 插件不适用于 grails 3.x,但在 repo 自述文件中有一些信息。我将在此处复制/粘贴:

此插件不适用于 Grails 3。要在 Grails 3 项目中处理 CORS,您只需在 src/main/java 下的某处创建一个 servlet 过滤器:

@Priority(Integer.MIN_VALUE)
public class CorsFilter extends OncePerRequestFilter {

    public CorsFilter() { }

    @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);
    }
}

引用grails-app/conf/spring/resources.groovy中的过滤器:

beans = {
     corsFilter(CorsFilter)
}

希望这对某人有所帮助。

【讨论】:

  • 我尝试了您的解决方案,即使正在调用过滤器并将标头添加到响应中,我仍然收到 403,知道吗? (我在这里提出了我的问题stackoverflow.com/questions/42460853/…)。谢谢
【解决方案2】:

我将 grails-3.0.2/grails-spring-websocket-2.0.0 示例应用程序推送到 https://github.com/zyro23/so-30891198,这表明它应该可以工作。

curl -H "Origin: http://localhost:8080" --verbose http://localhost:8080/stomp/info
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:8080

curl -H "Origin: http://localhost" --verbose http://localhost:8080/stomp/info
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost

第二个示例使用 grails-2.5.0/spring-websocket-1.3.0:https://github.com/zyro23/so-30891198-2

curl -H "Origin: http://localhost:8080" --verbose http://localhost:8080/so-30891198-2/stomp/info
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:8080

curl -H "Origin: http://localhost" --verbose http://localhost:8080/so-30891198-2/stomp/info
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost

【讨论】:

  • 谢谢,我会尽快检查,如果我发现我做错了什么,会通知你。
  • 在我的设置中,您的第一个测试命令有效。第二个返回: * 在 DNS 缓存中找不到主机名 * 正在尝试 ::1... * 已连接到 localhost (::1) 端口 8080 (#0) > GET /stomp/info HTTP/1.1 > User-Agent: curl/7.39.0 > 主机:localhost:8080 > 接受:/ > 来源:localhost >
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 2017-03-26
  • 2015-05-19
  • 2020-05-02
  • 2011-10-15
  • 2017-02-02
相关资源
最近更新 更多