source

Angular 4.3.3 HttpClient : 응답의 헤더에서 값을 얻는 방법은?

factcode 2023. 9. 16. 09:56
반응형

Angular 4.3.3 HttpClient : 응답의 헤더에서 값을 얻는 방법은?

(편집자: VS 코드, 타이프스크립트: 2.2.1 )

목적은 요청 응답의 헤더를 가져오는 것입니다.

서비스의 HttpClient를 사용한 POST 요청 가정

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

import {
    HttpClient,
    HttpHeaders,
} from "@angular/common/http";

@Injectable()
export class MyHttpClientService {
    const url = 'url';

    const body = {
        body: 'the body'
    };

    const headers = 'headers made with HttpHeaders';

    const options = {
        headers: headers,
        observe: "response", // to display the full response
        responseType: "json"
    };

    return this.http.post(sessionUrl, body, options)
        .subscribe(response => {
            console.log(response);
            return response;
        }, err => {
            throw err;
        });
}

Http 클라이언트 각도 설명서

첫번째 문제는 Typescript 오류가 발생한다는 것입니다.

'Argument of type '{ 
    headers: HttpHeaders; 
    observe: string; 
    responseType: string;
}' is not assignable to parameter of type'{ 
    headers?: HttpHeaders;
    observe?: "body";
    params?: HttpParams; reportProgress?: boolean;
    respons...'.

Types of property 'observe' are incompatible.
Type 'string' is not assignable to type '"body"'.'
at: '51,49' source: 'ts'

실제로 ref post() method로 가면 이 프로토타입을 가리킵니다(I Use VS code)

post(url: string, body: any | null, options: {
        headers?: HttpHeaders;
        observe?: 'body';
        params?: HttpParams;
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<ArrayBuffer>;

하지만 과적된 방법을 원합니다.

post(url: string, body: any | null, options: {
    headers?: HttpHeaders;
    observe: 'response';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<HttpResponse<Object>>;

그래서 저는 이 구조로 이 오류를 수정하려고 했습니다.

  const options = {
            headers: headers,
            "observe?": "response",
            "responseType?": "json",
        };

그것은 컴파일!다만 json 형식으로 body request를 받을 뿐입니다.

또한 필드 이름의 끝에 ? 기호를 넣어야 하는 이유는 무엇입니까?타이프스크립트 사이트에서 본 것처럼, 이 기호는 선택 사항임을 사용자에게 알려주어야 합니다.

저는 또한 ?표시 없이 모든 필드를 사용하려고 했습니다.

편집

Angular 4에서 제안한 솔루션을 API 응답에서 헤더를 얻는 방법을 시도했습니다.지도 솔루션의 경우:

this.http.post(url).map(resp => console.log(resp));

Typescript 컴파일러는 지도가 Observable의 일부가 아니기 때문에 존재하지 않는다고 말합니다.

저도 이거 먹어봤어요.

import { Response } from "@angular/http";

this.http.post(url).post((resp: Response) => resp)

컴파일되지만 지원되지 않는 미디어 유형 응답이 나타납니다.이러한 솔루션은 "Http"에서는 작동하지만 "HttpClient"에서는 작동하지 않습니다.

EDIT 2

@Supamiu 솔루션으로 지원되지 않는 미디어 유형도 제공되므로 헤더에 오류가 발생합니다.따라서 위의 두 번째 솔루션(응답 유형 포함)도 작동해야 합니다.하지만 개인적으로 "Http"와 "HttpClient"를 혼용하는 것은 좋지 않다고 생각하여 Supamiu의 솔루션을 유지하겠습니다.

내용만 관찰하는 대신 전체 응답을 관찰할 수 있습니다.는 ①번을 통과해야 .observe: responseoptions함수 호출의 매개 변수입니다.

http
  .get<MyJsonData>('/data.json', {observe: 'response'})
  .subscribe(resp => {
    // Here, resp is of type HttpResponse<MyJsonData>.
    // You can inspect its headers:
    console.log(resp.headers.get('X-Custom-Header'));
    // And access the body directly, which is typed as MyJsonData as requested.
    console.log(resp.body.someField);
  });

HttpClient 설명서 참조

"응답"을 "몸"으로 사용할 수 있도록 유형 캐스트의 주요 문제

우리는 그렇게 다룰 수 있습니다.

const options = {
    headers: headers,
    observe: "response" as 'body', // to display the full response & as 'body' for type cast
    responseType: "json"
};

return this.http.post(sessionUrl, body, options)
    .subscribe(response => {
        console.log(response);
        return response;
    }, err => {
        throw err;
    });

실제로 주요 문제는 타이프스크립트 문제였습니다.

post() 코드에서는 옵션이 매개 변수에 직접 선언되어 "익명의" 인터페이스로 사용되었습니다.

해결책은 옵션을 매개 변수 내부에 원시 상태로 직접 배치하는 것이었습니다.

http.post("url", body, {headers: headers, observe: "response"}).subscribe...

상위 답변의 솔루션을 사용하고 액세스 권한이 없는 경우.keys()아니면.get()위에response.headers합니다. , xhr이 fetch 합니다 하는지 를 합니다 하는지 를

가져오기 요청이 기본값이지만, xhr 전용 헤더가 있는 경우 Angular는 xhr을 사용합니다(예: x).x-www-form-urlencoded).

사용자 지정 응답 헤더에 액세스하려는 경우 Access-Control-Exposure-Headers라는 다른 헤더로 해당 헤더를 지정해야 합니다.

위 솔루션을 사용해도 CORS 요청인 경우 커스텀 헤더를 검색할 수 없는 경우가 있습니다.이 경우 서버 측에서 원하는 헤더를 화이트리스트에 추가해야 합니다.

예:액세스 제어-노출-헤더: X-총 카운트

아래 방법은 저에게 완벽하게 효과가 있었습니다(현재 Angular 10).또한 임의 파일 이름을 설정하지 않고 대신 컨텐츠-디스포지션 헤더에서 파일 이름을 가져옵니다.

this._httpClient.get("api/FileDownload/GetFile", { responseType: 'blob' as 'json', observe: 'response' }).subscribe(response =>  { 
    /* Get filename from Content-Disposition header */
    var filename = "";
    var disposition = response.headers.get('Content-Disposition');
    if (disposition && disposition.indexOf('attachment') !== -1) {
        var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
        var matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
    }
    // This does the trick
    var a = document.createElement('a');
    a.href = window.URL.createObjectURL(response.body);
    a.download = filename;
    a.dispatchEvent(new MouseEvent('click'));
})

다른 개발자들이 말했듯이 헤더와 바디를 결합하기 위해서는 다음과 같은 방식으로 관찰자 산출물의 유형을 정의해야 합니다.

http.post("url", body, {headers: headers, observe: "response" as "body"})

그런 다음 파이프 또는 구독 영역에서 본문 및 헤더에 액세스할 수 있습니다.

http.post("url", body, {headers: headers, observe: "response" as "body"})
.pip(
  tap(res => {
   // res.headers
   // res.body
  })
)
.subscribe(res => {
   // res.headers
   // res.body
})

언급URL : https://stackoverflow.com/questions/45505619/angular-4-3-3-httpclient-how-get-value-from-the-header-of-a-response

반응형