(エディター:VS Code; TypeScript: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;
});
}
HttpClient Angular Documentation
最初の問題は、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'
実際、post()メソッドのrefに移動すると、このプロトタイプをポイントします(VSコードを使用します)
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形式のように、本文リクエストを取得するだけです。
さらに、なぜ私は置く必要がありますか?フィールドの名前の最後にある記号? TypeScriptサイトで見たように、このシンボルはオプションであることをユーザーに伝える必要がありますか?
また、すべてのフィールドを使用しようとしました。マーク
編集
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ソリューションでサポートされていないメディアタイプも取得するため、ヘッダーでエラーになります。したがって、上記の2番目のソリューション(応答タイプを使用)も機能するはずです。しかし、個人的には、「Http」と「HttpClient」を混在させるのは良い方法ではないと思うので、Supamiuのソリューションを維持します。
コンテンツのみではなく、完全な応答を確認できます。そのためには、observe: response
を関数呼び出しのoptions
パラメーターに渡す必要があります。
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;
});
実際、主な問題はTypeScriptの問題でした。
Post()のコードでは、オプションはパラメーターで直接宣言されているため、「匿名」インターフェースとして使用されます。
解決策は、オプションを直接パラメーター内のrawに配置することでした
http.post("url", body, {headers: headers, observe: "response"}).subscribe...
一番上の回答のソリューションを使用し、response.headers
で.keys()
または.get()
にアクセスできない場合は、xhrではなくfetchを使用していることを確認してください。
取得リクエストはデフォルトですが、Angularは、xhrのみのヘッダーが存在する場合はxhrを使用します(例:x-www-form-urlencoded
)。
カスタムレスポンスヘッダーにアクセスしようとしている場合は、 Access-Control-Expose-Headers と呼ばれる別のヘッダーでそれらのヘッダーを指定する必要があります。