Как включить CORS в Grails 3.0.1

Я хотел бы сделать перекрестное происхождение, используя Grails на стороне сервера. Единственная документация, которую я нашел, - это

https://grails.org/plugin/cors

но это для старой версии Grails. Другая документация, которую я нашел, для spring:

https://spring.io/guides/gs/rest-service-cors/

поэтому я добавил папку SimpleCorsFilter.groovy в init/myproject/, но я не знаю, как подключить этот компонент к resources.groovy

Ответ 1

Чтобы быть конкретным, вот какой код работает. Обратите внимание, что имя перехватчика должно соответствовать имени вашего контроллера (здесь, 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 }
}

Ответ 2

Мы использовали обычный фильтр сервлета с записью в 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.

Ответ 3

Итак, если вы попадете сюда , используя grails 3.2. +, вы можете использовать способ по умолчанию.

Перейдите к application.yml и добавьте:

grails:
    cors:
        enabled: true

Он добавит Access-Control-Allow-Origin '*'. Если вы хотите что-то другое, посмотреть эту страницу

Ответ 4

Я играл с картой emberjs вместе с приложением Grails 3.0 для отдыха, когда меня поразила проблема CORS. Следуя шагам в этой статье, http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/ помог мне разобраться.

В статье показано, как вы можете использовать новые Interceptors для создания класса 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, которая не была возвращена,

С помощью этого ответа fooobar.com/questions/497968/... я изменил класс 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

Вам следует использовать новый API-интерфейс перехватчиков grails. (https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors)

Вы можете создать перехватчик с помощью команды grails create-interceptor. Для перехватчика CORS я бы использовал метод after() этого Interceptor и настроил его для соответствия всем запросам (или просто запросам, которые вам нужны). Вы можете использовать объект response в этом методе, поэтому настройка заголовков должна быть аналогична случаю, описанному в документации Spring.

Ответ 6

Самое чистое и простое решение для grails 3.1.x, которое я нашел, - это добавить CorsFilter по умолчанию для Apache:

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 также подходит