Запрос OPTIONS для отдыха между доменами с использованием CORS - PullRequest
4 голосов
/ 10 ноября 2011

На стороне клиента я использую Ajax.post (jquery 1.5) с json.На стороне сервера я использую rest resteasy-jaxrs-2.0.1.GA.Я нашел где-то, что я должен добавить пару заголовков к ответу сервера, и я сделал следующий фильтр:

public void doFilter(   ServletRequest req,
                        ServletResponse res,
                        FilterChain filterChain)
    throws IOException, ServletException {

    MyServletRequestWrapper httpReq    = new MyServletRequestWrapper((HttpServletRequest)req);
    HttpServletResponse    httpRes   = (HttpServletResponse)res;

    HttpSession session = httpReq.getSession();


    httpRes.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    httpRes.addHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");

   if (((HttpServletRequest) req).getMethod().equals("OPTIONS")){
        httpRes.addHeader(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS, PUT, DELETE");
        httpRes.addHeader(ACCESS_CONTROL_ALLOW_HEADERS, "content-type, x-requested-with, x-requested-by");
   }

  filterChain.doFilter(httpReq, httpRes);

}

Это работает хорошо, потому что каждый отдельный ответ GET выше заголовков добавляется.Проблема появляется, когда я хочу использовать запрос POST.Когда я использую Ajax.post, сначала сервер получает запрос OPTIONS, и у меня появляется следующая ошибка:

Failed executing OPTIONS [REST_PATH] org.jboss.resteasy.spi.DefaultOptionsMethodException: No resource method found for options, return OK with Allow header

Чтобы устранить вышеуказанную ошибку, я пытался добавить метод вызова с тем жепуть как POST ([REST_PATH]), но с аннотацией @OPTION.В этом случае javac сказал мне, что символ: класс OPTIONS не может быть найден, даже если в прилагаемой библиотеке jaxrs есть класс OPTION.class.

Есть идеи, как это исправить?Буду очень признателен за любые подсказки.

Ответы [ 4 ]

1 голос
/ 10 августа 2017

Когда я пытался вызвать свой сервис с клиентом Angular 2, RestEasy отвечал на предпечатные запросы со статусом HTTP 500 и следующей ошибкой.

RESTEASY003655: не найден метод ресурса для параметров, верните OK с помощью Разрешить заголовок

Я пытался CorsFilter RestEasy , но я хотел бы предложить простую альтернативу. Что если вы не хотите писать код, обрабатывающий вызов OPTIONS для каждой из ваших конечных точек?

Я реализовал простой фильтр, который:

  1. Применяет к ответу необходимый заголовок CORS.
  2. Возвращает код состояния HTTP 200 при вызове конечной точки с помощью метода OPTIONS. Вы сообщаете клиенту, что его предварительные запросы CORS были приняты.

Вот код. Не стесняйтесь уточнять фильтр, если вы хотите отправить обратно 200 только при запросе «реальной» конечной точки.

@Provider 
public class CorsFilter implements ContainerResponseFilter {  

  @Override
  public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
    MultivaluedMap<String, Object> headers = responseContext.getHeaders();
    headers.add("Access-Control-Allow-Origin", "*"); // If you want to be more restrictive it could be localhost:4200
    headers.add("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS"); // You can add HEAD, DELETE, TRACE, PATCH
    headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, Accept-Language"); // You can add many more

    if (requestContext.getMethod().equals("OPTIONS"))
        responseContext.setStatus(200);
}}

Убедитесь, что также понимает CORS .

1 голос
/ 07 апреля 2013

Этот вопрос довольно старый, но в качестве справки для других с похожими проблемами - совсем недавно я наткнулся на хороший «фильтр CORS», который вы, возможно, захотите использовать. Это просто вопрос добавления следующих строк в ваш web.xml, и он работает как шарм.

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>CORS</filter-name>
    <servlet-name>MyServletNameGoesHere</servlet-name>
</filter-mapping>

и зависимость maven:

<dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>1.5.1</version>
</dependency>
0 голосов
/ 22 января 2015

В tomcat есть встроенный фильтр CORS.http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
0 голосов
/ 09 октября 2014

Фильтр CORS может быть в порядке.Я хотел бы отметить, как вы написали: «Чтобы устранить вышеуказанную ошибку, я пытался добавить вызов метода с тем же путем, что и POST ([REST_PATH]), но с аннотацией @OPTION. В этом случае javac сказал мне, что символ: класс OPTIONS могне найти ", что у вас там была опечатка вместо @OPTION<strong>S</strong>, которую вы написали @OPTION без <strong>S</strong>:)

...