中安拓也のブログ

プログラミングについて書くブログ

【Angular】HTTPのレスポンスヘッダを取得したい

HTTPのレスポンスヘッダの一つであるETagを取得しようとして四苦八苦した話。

バージョン情報

JavaScriptフレームワークであるAngularを使います

  • Angular: 5.2.9

  • ionic-angular: 3.9.2

ETagとは

https://ja.wikipedia.org/wiki/HTTP_ETag

ETag(エンティティタグ)は、HTTPにおけるレスポンスヘッダの1つである。これは、HTTPにおけるキャッシュの有効性確認の手段の1つであり、ETagを利用してクライアントから条件付きのリクエストを行うことができる。そうすることで、コンテンツが変わらなければレスポンスをすべて返す必要がなくなるので、キャッシュを効率化し、回線帯域を節約できるようになる

本記事は、ETagを取得した段階で終了するので、ETagの中身については、特にツッコミません。

Angularでヘッダーを取得する

Angularのバージョン4.3以降で、HttpClientModuleが導入されたことにより、レスポンスボディだけでなくヘッダーも受け取りたいときは、オプション{ observe: 'response' }を追加する必要があります。また、今回のリクエスト対象が画像のこともあり、{ responseType: 'blob' }も指定しています。

this.http
      .get(imgUrl, { observe: 'response', responseType: 'blob' })
      .subscribe(res => {
        const etag = res.headers.get('ETag');
        console.log(`Etag: ${etag}`);
      });
});

上記のコードでETagが取得できるはずです.........しかしできない。

Etagを取得できない理由: Access-Control-Expose-Headers

ETag(HTTP Headerの一種)を取得できない理由は、フロント(Angular)側でなく、サーバー(API)側にありました。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

The Access-Control-Expose-Headers response header indicates which headers can be exposed as part of the response by listing their names.By default, only the 6 simple response headers are exposed If you want clients to be able to access other headers, you have to list them using the Access-Control-Expose-Headers header.

フロント側から、デフォルトでアクセス可能なのは、Cache-Controlなどの6つのHttpヘッダーのみで、ETagだったり他のカスタムヘッダーにアクセスするときは、API側で、Access-Control-Expose-Headers: ETagのように設定してあげる必要があります。

参考サイト

javascript - Get response custom headers for cross-origin request - Stack Overflow

https://github.com/angular/angular/issues/5237