Я создаю фронтенд-приложение с React и Redux и использую axios для выполнения запросов. Я хотел бы получить доступ ко всем полям в заголовке ответа. В браузере я могу просмотреть заголовок и вижу, что все необходимые мне поля присутствуют (такие как token, uid и т.д...), но когда я вызываю

const request = axios.post(`${ROOT_URL}/auth/sign_in`, props);
request.then((response)=>{
  console.log(response.headers);
});

Я получаю только

Object {content-type: "application/json; charset=utf-8", cache-control: "max-age=0, private, must-revalidate"}

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

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

Лучшее.

TWONEKSONE

Ответы (13)

В случае CORS-запросов браузеры по умолчанию могут получить доступ только к следующим заголовкам ответа:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

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

Access-Control-Expose-Headers: Access-Token, Uid

Я столкнулся с той же проблемой. Я сделал это в своем WebSecurity.java, дело в методе setExposedHeaders в конфигурации CORS.

@Bean
CorsConfigurationSource corsConfigurationSource() {

    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.setAllowedOrigins(Arrays.asList(FRONT_END_SERVER));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
    
    // Это позволит нам раскрыть заголовки
    configuration.setExposedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
            "Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"));
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

Я надеюсь, что это сработает.

Нестандартные HTTP-заголовки не могут быть доступны на стороне клиента из-за ограничений CORS. Вам необходимо добавить параметр Access-Control-Expose-Headers на стороне сервера.

Что такое Access-Control-Expose-Headers?
Пожалуйста, зайдите на https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

По умолчанию отображаются только эти HTTP-заголовки:

  • Cache-Control
  • Content-Language
  • Content-Length
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Для пользовательских HTTP-заголовков необходимо настроить Access-Control-Expose-Headers в заголовках ответа.

Если вы используете Django на стороне сервера, вы можете использовать django-cors-headers (https://pypi.org/project/django-cors-headers/) для управления настройками CORS.

Например, с помощью django-cors-headers вы можете добавить список HTTP-заголовков, которые должны быть открыты для браузера с помощью настройки CORS_ALLOW_HEADERS

.
from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = list(default_headers) + [
    'my-custom-header',
]

В случае, если вы используете Laravel 8 на стороне back-end с правильно настроенным CORS, добавьте эту строку в config/cors.php:

'exposed_headers' => ['Authorization'],

[расширяя сказанное @vladimir]

если вы используете Django
и django-cors-headers для разрешения/контроля CORS, вы должны установить следующее, в вашем settings.py

CORS_EXPOSE_HEADERS = ['yourCustomHeader']

для помощи по django

CORS_EXPOSE_HEADERS = [
        'your header'
    ]

попробуйте так

            .then(res =>{
                console.log(res);
                console.log(res.headers['x-total-count']);
                setTotalRecords(res.headers['x-total-count']);
                setTableData(res.data);
            });

Для SpringBoot2 просто добавьте

httpResponse.setHeader("Access-Control-Expose-Headers", "custom-header1, custom-header2");

в код реализации CORS-фильтра для внесения в белый список custom-header1 и custom-header2 и т.д.

Согласно официальным документам:

Это может помочь, если вам нужны HTTP-заголовки, с которыми ответил сервер. Все имена заголовков приводятся в нижнем регистре и могут быть доступны с помощью обозначения скобок. Пример: response.headers['content-type'] даст что-то вроде: headers: {},

В Spring Boot 2, если вы не хотите использовать глобальную настройку CORS, вы можете сделать это на уровне метода или класса/контроллера, используя @CrossOrigin adnotation с атрибутом exposedHeaders.

Например, чтобы добавить заголовок authorization для методов YourController:

@CrossOrigin(exposedHeaders = "authorization")
@RestController
public class YourController {
    ...
}

Есть еще одна подсказка, которой нет в этом разговоре. для asp.net core 3.1 сначала добавьте ключ, который вам нужен, в заголовок, примерно так:

Response.Headers.Add("your-key-to-use-it-axios", "your-value");

где вы определяете политику cors (обычно это в Startup.cs), вы должны добавить этот ключ в WithExposedHeaders следующим образом.

          services.AddCors(options =>
        {
        options.AddPolicy("CorsPolicy",
            builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .AllowAnyOrigin()
                .WithExposedHeaders("your-key-to-use-it-axios"));
        });
    }

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

          localStorage.setItem("your-key", response.headers["your-key-to-use-it-axios"]);

Вы можете использовать его на стороне клиента, обратившись к нему следующим образом:

const jwt = localStorage.getItem("your-key")

Столкнулся с той же проблемой в asp.net core Надеюсь, это поможет

public static class CorsConfig
{
    public static void AddCorsConfig(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                .WithExposedHeaders("X-Pagination")
                );
        });
    }
}

Это действительно помогло мне, спасибо Ник Уральцев за ваш ответ.

Для тех, кто использует nodejs с корами:

...
const cors = require('cors');

const corsOptions = {
  exposedHeaders: 'Authorization',
};

app.use(cors(corsOptions));
...

В данном случае вы отправляете ответ способом res.header('Authorization', `Bearer ${token}`).send();

.

2022 WebDevInsider