Отсутствует заголовок в ответе HTTP из-за CORS

Я использую embedded jetty через maven с версией <jetty.version>9.4.19.v20190610</jetty.version>

Я использую фильтр CORS следующим образом:

        FilterHolder holder = new FilterHolder(CrossOriginFilter.class);
        holder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
        holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
        holder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,DELETE,OPTIONS");
        holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_METHODS_HEADER, "*");
        holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_HEADERS_HEADER, "true");
        holder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM,
                "Access-Control-Request-Method,x-csrftoken,ClientKey,If-None-Match,Access-Control-Request-Headers,Authorization,X-Requested-With,Prefer,Content-Type,X-Auth-Token,Accept,Origin,X-Requested-With,Pragma,Refer,Referer,User-Agent,Host,Connection,Cache-Control,Accept-Language,Accept-Encoding,Content-Length,sec-fetch-mode,sec-fetch-site");
        holder.setName("cross-origin");


        staticServletHandler.addFilter(holder, "/*", EnumSet.of(DispatcherType.REQUEST));

Я могу запросить конечную точку REST, размещенную на пристани, с любого сервера без ошибки CORS. Я использую следующий код JSjquery) для доступа к конечной точке (я запускаю код в chrome):

$.ajax({
          type:'Get',
          cache: false,
          dataType: 'json',
          url: myurl,
          success:((data,textstatus,request)=>{
            this.etag=request.getResponseHeader('E-Tag'); //null if JS is executed on another server
          }),
      });

Если я размещаю код JS на jetty, я дополнительно могу получить доступ к E-Tag, если я размещаю код на другом сервере, я ПОЛУЧУ ДАННЫЕ, НО НЕ E-TAG. Итак, если JS Код находится на том же сервере, что и конечная точка, после чего я получаю заголовок ответа. Если он расположен на другом сервере, заголовки удаляются. Следовательно, я предполагаю, что это ошибка CORS (я не получаю ошибку). Как мне настроить причал, чтобы он работал для удаленного запроса?

Дополнительная информация: я создаю заголовок электронной метки на причале следующим образом:

return Response.status(200).entity(status).header("E-Tag","abc").build();

EDIT: я добавил следующую строку:

holder.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER, "Content-Length, X-Kuma-Revision, E-Tag");

но заголовок E-Tag по-прежнему отсутствует. Сервер определенно добавляет заголовок к ответу, как показано на следующем снимке экрана Postman.

введите здесь описание изображения


person user3579222    schedule 02.12.2019    source источник
comment
Запутанный вопрос. Ваш вопрос указывает, что это работает для Jetty, тогда вы спрашиваете, как заставить его работать для Jetty??   -  person Joakim Erdfelt    schedule 02.12.2019
comment
Я могу сделать запрос, но не получаю заголовок, если JS размещен на другом сервере.   -  person user3579222    schedule 02.12.2019
comment
Спасибо за ваш отзыв, я попытался уточнить свой вопрос   -  person user3579222    schedule 02.12.2019


Ответы (1)


Чтобы запросы с другого сервера могли получить доступ к заголовкам, необходимо отправить заголовок Access-Control-Expose-Headers вместе с ответом. Значение заголовка должно быть списком имен заголовков, разделенных запятыми, которые вы хотите показать.

Пример: Access-Control-Expose-Headers: Content-Length, X-Kuma-Revision

См. ссылку для разработчиков Mozilla для получения дополнительной информации и ясности.

Реализация: добавьте следующий параметр инициализации:

holder.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM, "Content-Length, X-Kuma-Revision, E-Tag");
person Pardhu    schedule 02.12.2019
comment
Реализация не соответствует вашему редактированию. Вам нужно добавить параметр EXPOSED_HEADERS_PARAM, аналогичный ALLOWED_HEADERS_PARAM. Обратитесь к моему отредактированному ответу - person Pardhu; 03.12.2019
comment
CrossOriginFilter.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER — это константа со значением Access-Control-Expose-Headers --›, поэтому моя реализация кажется идентичной вашей... или я что-то контролирую? - person user3579222; 03.12.2019
comment
Добавьте строку: holder.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM, "Content-Length, X-Kuma-Revision, E-Tag"); Not CrossOriginFilter.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER - person Pardhu; 03.12.2019