発生した事象
下記のコードを実行したところ、サーバが渡した応答ヘッダをクライアントが受け取れなかった。
サンプルコード
await this.$axios.post('http://localhost:8000/user/', {
id: this.id,
password: this.password
}).then(function (response) {
console.log(response.headers)
}
console.log()の出力結果を見ると、response.headersには下記の2つしか取れない。
cache-control: "no-cache, private"
content-type: "application/json"
だがChromeのデベロッパーツールのNetworkを確認すると、他にもたくさんのResponse Headerが確認できた。
環境
今回の事象は本構成とは特に関係ないが念のため記載しておく。
- サーバ: PHP + Laravel
- クライアント: Vue.js + axios + Chrome
原因
今回APIサーバと、Vue.jsのサーバを分けて開発していた。
このためAPIサーバは別ドメインにあるのだが、CORS通信でHTTPの応答ヘッダにAccess-Control-Expose-Headersを設定していなかった。
Access-Control-Expose-Headersが未指定の場合、Chromeなどのブラウザはセキュリティの観点で一部のヘッダ情報のみしかJavaScriptのコードからみえないように振舞う。
この制限を解除したい場合、サーバの応答ヘッダを以下のようにすることでクライアントのJavaScriptは全ての情報を取得できる
Access-Control-Expose-Headers: *
jsで取得できるレスポンスヘッダを明示した一部のヘッダのみに限定したい場合は、Access-Control-Expose-Headersへ許可するヘッダを列挙する。
以下のように設定することでクライアントは指定応答ヘッダのみを取得できる。
Access-Control-Expose-Headers: Access-Token, User-Id
Access-Token: xxx
User-Id: xxx
Secret-Info: xxx // これはAccess-Control-Expose-Headersに指定されてないのでjsから取れない
こちらもおススメ