web-dev-qa-db-fra.com

Angular 6 Obtenir les en-têtes de réponse avec le problème httpclient

J'utilise le code ci-dessous pour essayer d'extraire une valeur (ReturnStatus) à partir des en-têtes de réponse;

Keep-Alive: timeout=5, max=100
ReturnStatus: OK,SO304545
Server: Apache/2.4.29 (Win32) OpenSSL/1.0.2m

Le code;

import { Injectable } from '@angular/core';

import { Account } from './model/account';
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from "rxjs";
import { map, filter, catchError, mergeMap } from 'rxjs/operators';

 createOrder(url) : Observable<any> {

  return this._http.get(url, {withCredentials: true, observe: 'response'})
  .pipe(
    map((resp: any) => {
      console.log("response", resp);
      return resp;

    }), catchError( error => {
      console.log("createOrder error",error );
      alert("Create Order Service returned an error. See server log for mote details");
    return throwError("createOrder: " + error)

    })
  );
}

Cependant mon console.log suffit de donner;

HttpResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: 
"http://localhost/cgi-bin/dug.cgi/wh?Page… 
plateLocation=C:%5Ctemp%5Corderimporttemplate.txt", ok: true, …}

J'ai regardé sur ce site et d'autres sites pour trouver la bonne façon de faire ceci dans Angular mais en vain? Quelqu'un pourrait-il m'indiquer dans la bonne direction s'il vous plaît?

Merci beaucoup,

Marque.

9
Mark Beynon

Vous devez observer l'ensemble de la réponse comme décrit ci-dessous:

 createOrder(url) : Observable<HttpResponse<Object>>{

    return this.http.get<HttpResponse<Object>>(this.url, {observe: 'response'}).pipe(
         tap(resp => console.log('response', resp))
    );
}

Maintenant, à l'intérieur de resp vous pouvez accéder aux en-têtes. Un exemple

 createOrder(url) : Observable<HttpResponse<Object>>{

    return this.http.get<HttpResponse<Object>>(this.url, {observe: 'response'}).pipe(
         tap(resp => console.log('heaeder', resp.headers.get('ReturnStatus')))
    );
}

Si vous ne pouvez pas accéder à votre en-tête personnalisé, comme expliqué ci-dessus, c'est parce qu'un petit nombre d'en-têtes est exposé au javascript par défaut pour des raisons de sécurité. Probablement si vous ouvrez des outils de développement et inspectez vos en-têtes de réponse, vous devriez voir celui que vous souhaitez.

Qui peut choisir quels en-têtes sont exposés à javascript?

Les en-têtes exposés sont choisis par l'application Web (donc vos services Web ou votre backend. Évidemment, votre application Web peut être écrite en plusieurs langues et/ou en utilisant plusieurs frameworks.

Selon ce que vous utilisez, vous pouvez atteindre cet objectif de différentes manières.

Pour vous donner une idée de ce que vous devriez faire, je peux publier ma solution Spring. En classe qui étend WebSecurityConfigurerAdapter, vous devriez ajouter ces deux méthodes:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            // we don't need CSRF because our token is invulnerable
            .csrf().disable()
            .cors()
} 


@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
            "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("DELETE");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

Notez que j'ai désactivé csrf parce que j'utilise JWT. Notez que vous devez affiner les règles CorsFilter.

Comme vous pouvez le voir, j'ai ajouté Custom-Filter-Header dans cette ligne

config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
                "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");

Vous pouvez remplacer ceci Custom-Filter-Header avec votre ReturnStatus

17
firegloves