Axiosでレスポンスヘッダが取得できなかった (CORSなAPI)
標準的なレスポンスヘッダ以外の場合は、APIが返すレスポンスヘッダに Access-Control-Expose-Headers: ${レスポンスヘッダ名}
を追加する必要がある。
画面とAPIが別のドメインにあるWebアプリを作ってました。
以下、ここでは画面側URLが https://mywebapp.com
、API側URLが https://api.mywebapp.com
とします。
そのAPIがカスタムレスポンスヘッダ X-Piyopiyo
を返す仕様だったのですが、これがAxiosのレスポンスオブジェクトになぜか入ってこなくて、取得できませんでした。
import axios from 'axios';
const params = {
age: 14
};
const options = {
headers: { 'Content-Type': 'application/json;charset=utf-8' }
};
axios.post('https://api.mywebapp.com', params, options)
.then(res => {
console.log(res.headers);
})
.catch(err => {
// 略
});
headers:
cache-control: "max-age=999"
content-length: "9999"
content-type: "application/json"
res.headers
に X-Piyopiyo
がありません。
不可解だったのは、ブラウザの開発者ツールのレスポンスにはちゃんと X-Piyopiyo
が表示されてるところでした。JavaScriptの中からだけ、アクセスできないみたいです。
ググってたら以下のページを見つけました。
Axios get access to response header fields - Stack Overflow
どうやらCORSなWebAPIの場合、ブラウザ側で扱えるレスポンスヘッダの名称を、Access-Control-Expose-Headers
ヘッダで明示的に指定する必要があるようです。
Cache-Control
とか Content-Type
のような一般的なレスポンスヘッダならば不要みたいですが、今回は自分で定義したレスポンスヘッダなので必要でした。
ここで書いてる例の場合、WebAPI側のレスポンスヘッダに Access-Control-Expose-Headers
を追加して以下のようにしたら、Axiosの res.headers
に X-Piyopiyo
が入ってくるようになりました。
Content-Type: application/json;charset=utf-8
Access-Control-Allow-Origin: https://mywebapp.com
Access-Control-Expose-Headers: X-Piyopiyo
なお、Preflight (OPTIONSメソッド) のレスポンスヘッダには、特に Access-Control-Expose-Headers
は設定しなくて大丈夫なようです。