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.


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

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();


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.


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")
                );
        });
    }
}

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: {},


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.



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 {
    ...
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.