Axios erhalten Zugriff auf Antwortheaderfelder

159

Ich erstelle eine Frontend-App mit React und Redux und verwende Axios , um meine Anforderungen auszuführen. Ich möchte Zugriff auf alle Felder in der Kopfzeile der Antwort erhalten. In meinem Browser kann ich den Header überprüfen und sehen, dass alle Felder vorhanden sind, die ich benötige (wie Token, UID usw.), aber wenn ich anrufe

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

Ich verstehe nur

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

Hier ist mein Browser-Netzwerk-Tab, wie Sie sehen können, alle anderen Felder vorhanden.

Geben Sie hier die Bildbeschreibung ein

Beste.

TWONEKSONE
quelle
Wenn Sie axios.defaults.headers ausdrucken, erhalten Sie dann einen von denen, die Sie vermissen? Einige Header werden auf dieser Ebene konfiguriert, nicht bei jeder Anforderung (siehe github.com/mzabriskie/axios#global-axios-defaults )
Ben Hare
2
Ist es nicht axios.defaults.headersfür die Konfiguration der REQUEST-Header-Parameter? Ich muss auf die ANTWORT zugreifen. @ BenHare
TWONEKSONE
Übrigens, was Sie Anfrage genannt haben, ist keine Anfrage. Es ist ein Versprechen für Ihre Antwort. Ihre Anfrage war das, was Sie als Argumente an die post () -Methode übergeben haben.
Daniel

Antworten:

308

Bei CORS-Anforderungen können Browser standardmäßig nur auf die folgenden Antwortheader zugreifen:

  • Cache-Kontrolle
  • Inhaltssprache
  • Inhaltstyp
  • Läuft ab
  • Zuletzt geändert
  • Pragma

Wenn Sie möchten, dass Ihre Client-App auf andere Header zugreifen kann, müssen Sie den Header Access-Control-Expose- Headers auf dem Server festlegen :

Access-Control-Expose-Headers: Access-Token, Uid
Nick Uraltsev
quelle
Mein schlechtes Ich habe vergessen, diese Felder freizulegen.
TWONEKSONE
27
Wenn Sie Rails mit Rack-Cors verwenden, müssen Sie expose: ['Access-Token', 'Uid']den Ursprung wie resource '*', :headers => :any, :methods => [:get, :post, :put, :patch, :delete, :options, :head], expose: ['Access-Token', 'Uid']
folgt einstellen
3
Ich verstehe es nicht Wenn sie nicht verfügbar sind, warum werden die zusätzlichen Header im Browser angezeigt, nicht jedoch in der Axios-Antwort?
Adanilev
4
@adanilev, Browser ermöglichen es Ihnen, sie zu Debugging-Zwecken anzuzeigen, verhindern jedoch aus Sicherheitsgründen, dass Sie über APIs auf sie zugreifen. Es verhindert, dass Clients gesicherte Anmeldeinformationen von Servern erhalten, sodass der Server bestimmen kann, über welchen Zugriff ein Client verfügt. TLDR: Es wurde absichtlich aus Sicherheitsgründen durchgeführt
am
2
Ich habe dies in meiner NGINX-Konfigurationsdatei ... Ich sehe 'Access-Control-Expose-Headers' 'Authorization, X-Suggested-Filename, content-disposition' always; immer noch nur, dass ich content-type: "application/pdf" wirklich ziehen musscontent-disposition
Old Man Walter
17

Das hat mir wirklich geholfen, danke Nick Uraltsev für deine Antwort.

Für diejenigen unter Ihnen, die nodejs mit cors verwenden :

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

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

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

In dem Fall, dass Sie die Antwort in der Art von senden res.header('Authorization', `Bearer ${token}`).send();

Cass
quelle
1
Für diejenigen, die sich fragen, könnten Sie auch hier ein Array übergeben: exponiertHeaders: ['Authorization', 'X-Total-Count']
Thiago Santana
10

Ich hatte das gleiche Problem. Y hat dies in meiner "WebSecurity.java" getan, es geht um die setExposedHeaders-Methode in der cors-Konfiguration.

@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;
}

Ich hoffe, es funktioniert.

Daniel Azamar
quelle
7

Konfrontiert das gleiche Problem in asp.net Kern Hoffe, das hilft

public static class CorsConfig
{
    public static void AddCorsConfig(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                .WithExposedHeaders("X-Pagination")
                );
        });
    }
}
Chitova263
quelle
1
Willkommen bei SO! Ihre Antwort mag korrekt sein, aber bei StackOverflow wird davon abgeraten, nur eine Antwort mit Postleitzahl zu posten. Bitte versuchen Sie zu erklären, wie Ihre Antwort die ursprüngliche Frage löst. Bitte lesen Sie dies auf, wie man eine bessere Antwort schreibt
nircraft
Danke, es hatte geholfen;)
Florian
2

Laut offiziellen Dokumenten :

Dies kann hilfreich sein, wenn Sie die HTTP-Header verwenden möchten , mit denen der Server geantwortet hat . Alle Headernamen sind in Kleinbuchstaben geschrieben und können über die Klammernotation aufgerufen werden. Beispiel: response.headers['content-type']gibt so etwas wie: headers: {},

Yogesh Bhatt
quelle
1

Für den SpringBoot2 einfach hinzufügen

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

zu Ihrem CORS-Filter-Implementierungscode, um eine Whitelist zu haben custom-header1und custom-header2etc.

JackTheKnife
quelle
0

für Django Hilfe

CORS_EXPOSE_HEADERS = [
        'your header'
    ]
VladimirDev
quelle