Javascript Angular 4.3.3 HttpClient:如何从响应头中获取值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45505619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:04:24  来源:igfitidea点击:

Angular 4.3.3 HttpClient : How get value from the header of a response?

javascriptangulartypescriptrequesttypescript2.0

提问by M.Lobry

( Editor: VS Code; Typescript: 2.2.1 )

(编辑器:VS Code;打字稿:2.2.1)

The purpose is to get the headers of the response of the request

目的是获取请求的响应头

Assume a POST request with HttpClient in a Service

假设在服务中使用 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;
        });
}

HttpClient Angular Documentation

HttpClient 角度文档

The first problem is that I have a Typescript error :

第一个问题是我有一个打字稿错误:

'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'

Indeed, when I go to the ref of post() method, I point on this prototype (I Use VS code)

确实,当我转到 post() 方法的 ref 时,我指向了这个原型(我使用 VS 代码)

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

But I want this overloaded method :

但我想要这个重载的方法:

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

So, I tried to fix this error with this structure :

所以,我试图用这个结构修复这个错误:

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

And It compiles! But I just get the body request as in json format.

它编译!但我只是以 json 格式获取正文请求。

Futhermore, why I have to put a ? symbol at the end of some name of fields ? As I saw on Typescript site, this symbol should just tell to the user that it is optional ?

此外,为什么我必须放一个?某些字段名称末尾的符号?正如我在 Typescript 网站上看到的,这个符号应该只是告诉用户它是可选的?

I also tried to use all the fields, without and with ? marks

我还尝试使用所有字段,没有和有?分数

EDIT

编辑

I tried the solutions proposed by Angular 4 get headers from API response. For the map solution:

我尝试了Angular 4 get headers from API response提出的解决方案。对于地图解决方案:

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

Typescript compiler tells that map does not exists because it is not a part of Observable

Typescript 编译器告诉 map 不存在,因为它不是 Observable 的一部分

I also tried this

我也试过这个

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

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

It compiles, but I get a unsupported Media Type response. These solutions should work for "Http" but it does not on "HttpClient".

它编译,但我得到一个不受支持的媒体类型响应。这些解决方案应该适用于“Http”,但不适用于“HttpClient”。

EDIT 2

编辑 2

I get also a unsupported media type with the @Supamiu solution, so it would be an error on my headers. So the second solution from above (with Response type) should works too. But personnaly, I don't think it is a good way to mix "Http" with "HttpClient" so I will keep the solution of Supamiu

我的@Supamiu 解决方案也得到了不受支持的媒体类型,因此我的标题会出错。所以上面的第二个解决方案(带有响应类型)也应该有效。但是个人而言,我认为将“Http”与“HttpClient”混合在一起不是一个好方法,所以我会保留Supamiu的解决方案

回答by Supamiu

You can observe the full response instead of the content only. To do so, you have to pass observe: responseinto the optionsparameter of the function call.

您可以观察完整的响应,而不仅仅是内容。为此,您必须传入函数调用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);
  });

See HttpClient's documentation

请参阅HttpClient 的文档

回答by Birbal Singh

main problem of typecast so we can use "response" as 'body'

类型转换的主要问题,因此我们可以使用“响应”作为“主体”

we can handle like

我们可以处理

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

回答by M.Lobry

Indeed, the main problem was a Typescript problem.

事实上,主要问题是打字稿问题。

In the code of post(), options was declared directly in the parameters, so, as an "anonymous" interface.

在 post() 的代码中,选项直接在参数中声明,因此,作为“匿名”接口。

The solution was to put directly the options in raw inside the parameters

解决方案是将选项直接放在参数中的 raw 中

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

回答by Kevin Beal

If you use the solution from the top answer and you don't have access to .keys()or .get()on response.headers, make sure that you're using fetch rather than xhr.

如果您使用顶级答案中的解决方案并且您无权访问.keys().get()on response.headers,请确保您使用的是 fetch 而不是 xhr。

Fetch requests are the default, but Angular will use xhr if xhr-only headers are present (e.x. x-www-form-urlencoded).

获取请求是默认的,但如果存在 xhr-only 标头(例如x-www-form-urlencoded),Angular 将使用 xhr 。

If you are trying to access any custom response headers, then you have to specify those headers with another header called Access-Control-Expose-Headers.

如果您尝试访问任何自定义响应标头,则必须使用另一个名为Access-Control-Expose-Headers 的标头指定这些标

回答by Rajantha Fernando

Some times even with the above solution you can't retrieve custom headers if it is CORS request. In that case you need to whitelist desired headers in server side.

有时即使使用上述解决方案,如果是 CORS 请求,您也无法检索自定义标头。在这种情况下,您需要在服务器端将所需的标头列入白名单。

For Example: Access-Control-Expose-Headers: X-Total-Count

例如:Access-Control-Expose-Headers:X-Total-Count