Перекрестное происхождение для POST - PullRequest
0 голосов
/ 24 октября 2018

У меня есть http-сервер Jetty с некоторыми службами отдыха на Джерси.Эти сервисы вызываются с веб-сайта React, который работает на Node-сервере.

Из-за перекрестного происхождения этой настройки мне пришлось добавить несколько заголовков HTTP.По сути, все мои веб-сервисы возвращают createOkResult(), который создается следующим образом.

@POST
@Path("orders/quickfilter")
@Consumes(MediaType.APPLICATION_JSON)
public Response getQuickFilterProductionOrders(String data) 
{
  ...
  return createOkResult(json.toString());
}

protected Response createOkResult(Object result)
{
  return buildCrossOrigin(Response.ok().entity(result));
}

protected static Response buildCrossOrigin(Response.ResponseBuilder responseBuilder)
{
  return responseBuilder.header("Access-Control-Allow-Origin", "*")
          .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
          .allow("OPTIONS")
          .build();
}

Для @GET веб-сервисов, которые работают нормально.Но когда я создаю сервис @POST, я просто не могу заставить его работать.

Браузеры (Chrome и Firefox) возвращают такие ошибки:

Доступ к XMLHttpRequest на«http://localhost:59187/rs/production/orders/quickfilter' от источника» http://localhost:3000' заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

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

postman screenshot

Это скриншот POST-запроса.

В моем клиентском интерфейсе (который работает на сервере узлов) я использую Axios API, который использует обещания, и мой запрос выглядит следующим образом:

const url = "http://localhost:59187/rs/production/orders/quickfilter";
const data = JSON.stringify(request);
const headers = { headers: { "Content-Type": "application/json" } };
const promise = axios.post(url, data, headers);

Прямо сейчас у меня ошибка HTTP 500. Если я удаляю заголовок типа контента, я получаю исключение неподдерживаемого носителя.Итак, у меня есть основания полагать, что с типом контента все в порядке.

1 Ответ

0 голосов
/ 05 ноября 2018

Пол Самсота указал мне правильное направление.В итоге я добавил фильтр к ServletContextHandler.В отличие от связанной статьи, мне не нужно было создавать этот фильтр с нуля.Существовал существующий класс фильтров, который я мог бы использовать: т.е. org.eclipse.jetty.servlets.CrossOriginFilter.

FilterHolder filterHolder = context.addFilter(CrossOriginFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
filterHolder.setInitParameter(CrossOriginFilter.CHAIN_PREFLIGHT_PARAM, "false");

Некоторые из вышеперечисленных параметров, вероятно, могут быть пропущены, поскольку они являются значениями по умолчанию.Но то, что мне показалось крайне важным, это установить CHAIN_PREFLIGHT_PARAM на false.

Один приятный побочный эффект - это то, что я могу упростить код реальных служб.Им больше не нужно добавлять специальные заголовки, теперь они могут просто возвращать Response.ok().entity(result).build();.

...