Axios accède aux champs d'en-tête de réponse

161

Je construis une application frontale avec React et Redux et j'utilise axios pour exécuter mes requêtes. Je souhaite avoir accès à tous les champs de l'en-tête de la réponse. Dans mon navigateur, je peux inspecter l'en-tête et je peux voir que tous les champs dont j'ai besoin sont présents (tels que token, uid, etc ...), mais quand j'appelle

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

Je reçois juste

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

Ici, l'onglet réseau de mon navigateur, comme vous pouvez le voir, tous les autres champs sont présents.

entrez la description de l'image ici

Bests.

TWONEKSONE
la source
Si vous imprimez axios.defaults.headers, cela vous donne-t-il celui qui vous manque? Certains en-têtes sont configurés à ce niveau, pas à celui de chaque requête (voir github.com/mzabriskie/axios#global-axios-defaults )
Ben Hare
2
N'est-ce pas axios.defaults.headerspour configurer les paramètres d'en-tête REQUEST? J'ai besoin d'accéder à celui de RESPONSE. @BenHare
TWONEKSONE
BTW, ce que vous avez appelé demande, n'est pas une demande. C'est une promesse pour votre réponse. Votre requête était ce que vous avez transmis à la méthode post () en tant qu'arguments.
Daniel

Réponses:

312

En cas de requêtes CORS, les navigateurs ne peuvent accéder par défaut qu'aux en-têtes de réponse suivants:

  • Contrôle du cache
  • Contenu-Langue
  • Type de contenu
  • Expire
  • Dernière modification
  • Pragma

Si vous souhaitez que votre application cliente puisse accéder à d'autres en-têtes, vous devez définir l'en - tête Access-Control-Expose-Headers sur le serveur:

Access-Control-Expose-Headers: Access-Token, Uid
Nick Uraltsev
la source
Mon mauvais j'ai oublié d'exposer ces champs.
TWONEKSONE
28
Si vous utilisez des rails avec Rack-Cors, vous devez définir expose: ['Access-Token', 'Uid']l'origine comme:resource '*', :headers => :any, :methods => [:get, :post, :put, :patch, :delete, :options, :head], expose: ['Access-Token', 'Uid']
CWitty
3
Je ne comprends pas. S'ils ne sont pas exposés, pourquoi les en-têtes supplémentaires sont-ils visibles dans le navigateur mais pas dans la réponse axios?
adanilev
4
@adanilev, les navigateurs vous permettent de les voir à des fins de débogage, mais vous empêchent d'y accéder via des API pour des raisons de sécurité. Il empêche les clients d'obtenir des informations d'identification sécurisées des serveurs, ce qui permet au serveur de déterminer l'accès d'un client. TLDR: c'est fait exprès pour la sécurité
erfling
2
Je l'ai dans mon fichier de configuration NGINX ... 'Access-Control-Expose-Headers' 'Authorization, X-Suggested-Filename, content-disposition' always; Je ne vois toujours que content-type: "application/pdf" vraiment besoin de tirercontent-disposition
Old Man Walter
17

Cela m'a vraiment aidé, merci Nick Uraltsev pour votre réponse.

Pour ceux d'entre vous qui utilisent nodejs avec des cors :

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

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

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

Dans le cas où vous envoyez la réponse sous la forme de res.header('Authorization', `Bearer ${token}`).send();

cass
la source
1
Pour ceux qui se demandent, vous pouvez également passer un tableau ici: ExposedHeaders: ['Authorization', 'X-Total-Count']
Thiago Santana
11

J'étais confronté au même problème. Vous avez fait cela dans mon "WebSecurity.java", il s'agit de la méthode setExposedHeaders dans la configuration 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;
}

J'espère que ca fonctionne.

Daniel Azamar
la source
7

Face au même problème dans le noyau asp.net J'espère que cela aide

public static class CorsConfig
{
    public static void AddCorsConfig(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy",
                builder => builder
                .WithExposedHeaders("X-Pagination")
                );
        });
    }
}
Chitova263
la source
1
Bienvenue à SO! Votre réponse est peut-être correcte, mais chez StackOverflow, il est déconseillé de poster uniquement le code de réponse. Veuillez essayer d'expliquer comment votre réponse résout la question initiale. s'il vous plaît lire ceci sur la façon d' écrire une meilleure réponse
nircraft
Merci, ça avait aidé;)
Florian
2

Selon la documentation officielle :

Cela peut aider si vous voulez les en-têtes HTTP avec lesquels le serveur a répondu . Tous les noms d'en-tête sont en minuscules et sont accessibles en utilisant la notation entre crochets. Exemple: response.headers['content-type']donnera quelque chose comme: headers: {},

Yogesh Bhatt
la source
1

Pour le SpringBoot2, ajoutez simplement

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

à votre code d'implémentation de filtre CORS pour avoir mis en liste blanche custom-header1, custom-header2etc.

JackTheKnife
la source
0

pour l'aide de django

CORS_EXPOSE_HEADERS = [
        'your header'
    ]
VladimirDev
la source
0

Pour Spring Boot 2, si vous ne souhaitez pas utiliser la configuration CORS globale, vous pouvez le faire par méthode ou par niveau de classe / contrôleur en utilisant une @CrossOriginannotation avec exposedHeadersatribute.

Par exemple, pour ajouter un en-tête authorizationpour les YourControllerméthodes:

@CrossOrigin(exposedHeaders = "authorization")
@RestController
public class YourController {
    ...
}
M. Dudek
la source