Axios получает доступ к полям заголовка ответа

161

Я создаю веб-приложение с React и Redux и использую axios для выполнения своих запросов. Я хотел бы получить доступ ко всем полям в заголовке ответа. В своем браузере я могу проверить заголовок и увидеть, что все необходимые мне поля присутствуют (например, токен, 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"}

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

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

Bests.

TWONEKSONE
источник
Если вы распечатываете axios.defaults.headers, это дает вам что-то из того, что вам не хватает? Некоторые заголовки настраиваются на этом уровне, а не на каждом из запросов (см. Github.com/mzabriskie/axios#global-axios-defaults )
Бен Хэйр,
2
Разве это не axios.defaults.headersдля настройки параметров заголовка REQUEST? Мне нужно получить доступ к ответу. @BenHare
TWONEKSONE
Кстати, то, что вы назвали запросом, не является запросом. Это обещание для вашего ответа. Ваш запрос был тем, что вы передали методу post () в качестве аргументов.
Даниэль

Ответы:

312

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

  • Cache-Control
  • Content-Language
  • Тип содержимого
  • Истекает
  • Последнее изменение
  • Pragma

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

Access-Control-Expose-Headers: Access-Token, Uid
Ник уральцев
источник
Мой плохой, я забыл выставить эти поля.
TWONEKSONE
28
Если вы используете Rails с Rack-Cors, вам нужно установить expose: ['Access-Token', 'Uid']источник как:resource '*', :headers => :any, :methods => [:get, :post, :put, :patch, :delete, :options, :head], expose: ['Access-Token', 'Uid']
CWitty
3
Я не понимаю Если они не отображаются, почему дополнительные заголовки видны в браузере, а не в ответе axios?
Аданилев
4
@adanilev, браузеры позволяют вам видеть их в целях отладки, но не позволяют получить к ним доступ через API по соображениям безопасности. Это предотвращает получение клиентами защищенных учетных данных с серверов, позволяя серверу определять, какой доступ имеет клиент. TLDR: это сделано специально для безопасности
erfling
2
У меня есть это в моем файле конфигурации NGINX ... 'Access-Control-Expose-Headers' 'Authorization, X-Suggested-Filename, content-disposition' always; Все еще только вижу, content-type: "application/pdf" действительно нужно тянутьcontent-disposition
Старик Уолтер
17

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

Для тех из вас , используя nodejs с CORS :

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

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

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

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

Касс
источник
1
Для тех, кто интересуется, вы также можете передать массив здесь :ctedHeaders: ['Authorization', 'X-Total-Count']
Тьяго Сантана
11

Я столкнулся с той же проблемой. Y сделал это в моем "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"));

    // This allow us to expose the headers
    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;
}

Надеюсь это работает.

Даниэль Азамар
источник
7

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

public static class CorsConfig
{
    public static void AddCorsConfig(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                .WithExposedHeaders("X-Pagination")
                );
        });
    }
}
Chitova263
источник
1
Добро пожаловать на ТАК! Ваш ответ может быть правильным, но в StackOverflow не рекомендуется отправлять ответ только по коду. Пожалуйста, попробуйте объяснить, как ваш ответ решает исходный вопрос. Прочтите это, пожалуйста, о том, как написать лучший ответ
nircraft
Спасибо, это помогло;)
Флориан
2

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

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

Йогеш Бхатт
источник
1

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

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

к вашему коду реализации фильтра CORS, чтобы иметь белый список custom-header1и custom-header2т. д.

JackTheKnife
источник
0

для помощи Джанго

CORS_EXPOSE_HEADERS = [
        'your header'
    ]
VladimirDev
источник
0

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

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

@CrossOrigin(exposedHeaders = "authorization")
@RestController
public class YourController {
    ...
}
М. Дудек
источник