Происхождение не разрешено Access-Control-Allow-Origin - как включить CORS с помощью простого веб-стека и guice

Я не уверен, что проблема связана с технологией или моим пониманием технологий.

У меня есть приложение html5, написанное в javascript и html, размещенном на сервере apache 2.2.

У меня есть Java-приложение, написанное в java, используя причал, guice, jackson, jersey, на котором размещена простая служба REST.

Оба приложения запускаются в одном и том же поле, один на порт 80 (приложение с чистым html5, размещенном на apache), другое на 8080 (чистое приложение Java, размещенное на причале/графике)

Я считаю, что ответ в заголовках отправляется обратно. Заголовки CORS сообщают браузеру, что вы разрешаете внешним приложениям ударять ваш api. Я не могу понять, как настроить мой Jetty, сервер Guice, чтобы вернуть правильные заголовки CORS.

Я использую встроенный сервер Jetty, поэтому у меня нет файла web.xml для добавления заголовков.

Это также может быть связано с тем, как сервер приложений HTML5 (в данном случае apache 2.2) обслуживает приложение.

В файле apache httpd.conf имеется запись:

LoadModule headers_module modules/mod_headers.so

<IFModule mod_headers>
    Header add Access-Control-Allow-Origin "*"
    Header add Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
    Header add Access-Control-Allow-Headers: X-PINGOTHER
    Header add Access-Control-Max-Age: 1728000  
</IfModule>

в моей конфигурации серфинга guice у меня есть следующее:

public class RestModule extends ServletModule{

    @Override
    protected void configureServlets() {
        bind(QuestbookService.class);

        // hook Jersey into Guice Servlet
        bind(GuiceContainer.class);

        // hook Jackson into Jersey as the POJO <-> JSON mapper
        bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

        Map<String, String> guiceContainerConfig = new HashMap<String, String>();
        guiceContainerConfig.put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES,
            HttpStatusCodeMetricResourceFilterFactory.class.getCanonicalName());
        serve("/*").with(GuiceContainer.class, guiceContainerConfig);
    }
}

Я думаю, что проблема в моем графическом конфиге, так как у меня нет места для установки заголовков ответов.

Я использую встроенный сервер причала, и, таким образом, я решил, что режим dev будет обходить всю проверку, но я мог ошибаться.

Спасибо за любые советы.

Ответ 1

Делать с конкретными требованиями моего приложения. Сервер должен быть полностью отделен от клиента. Клиент должен иметь возможность подключаться к коммуникационному серверу любым доступным способом.

Поскольку первая реализация этого приложения будет основана на REST, мне нужно иметь возможность принимать отдых из любого места.

Кроме того, я хочу полностью xml-конфигурацию, поэтому я использую Guice со встроенным сервером Jetty. Поскольку у меня нет файла web.xml, я не мог понять, как установить заголовки для разрешения CORS.

После долгих проб и ошибок и прочтения документации-подсказки я обнаружил, как добавить заголовки CORS к ответу, покидая сервер.

Класс Guice ServletModule позволяет вам добавлять фильтры в ваш контекст сервлета. Это позволяет мне передавать все запросы через данный сервлет.

Так как я пытаюсь создать приложение отдыха, которое отвечает на запросы CORS, мне нужен фильтр, который добавляет заголовки cors к ответу на любой запрос.

Поэтому, чтобы включить cors на моем встроенном сервере, используя guice, я создал фильтр, который выглядит следующим образом:

@Singleton
public class CorsFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain filterChain) throws IOException, ServletException {

        if(response instanceof HttpServletResponse){
        HttpServletResponse alteredResponse = ((HttpServletResponse)response);
        addCorsHeader(alteredResponse);
    }

    filterChain.doFilter(request, response);
    }

    private void addCorsHeader(HttpServletResponse response){
        //TODO: externalize the Allow-Origin
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
        response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
        response.addHeader("Access-Control-Max-Age", "1728000");
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig filterConfig)throws ServletException{}
}

Guice предоставляет абстрактный класс, который позволяет настраивать сервлет Guice.

Модуль конфигурации выглядит следующим образом:

public class RestModule extends ServletModule{

    @Override
    protected void configureServlets() {
        bind(MyServiceClass.class);

        // hook Jersey into Guice Servlet
        bind(GuiceContainer.class);

        // hook Jackson into Jersey as the POJO <-> JSON mapper
        bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

        Map<String, String> guiceContainerConfig = new HashMap<String, String>();

        serve("/*").with(GuiceContainer.class, guiceContainerConfig);

        filter("/*").through(CorsFilter.class);
    }
}

Теперь guice будет добавлять заголовки cors к каждому ответу. Позволяет моему чистому приложению HTML 5 общаться с ним независимо от того, где оно обслуживается.

Ответ 2

Просто вставьте одну строку в ваш файл кода

response.addHeader("Access-Control-Allow-Origin", "*");

Замените * на http://www.yoursite.com, если хотите разрешить только для определенного домена

Ответ 3

Добавление этого к вашему httpServletResponse на стороне java, то есть на стороне сервера, решит проблему.

 httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
 httpServletResponse.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
 httpServletResponse.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
 httpServletResponse.addHeader("Access-Control-Max-Age", "1728000");