🤯

2021年版 Nuxt.js + axios (module) 外部API利用 CORS 回避

2021/05/13に公開

概要

Nuxt から 自前実装の外部APIを利用する際の実装について解説します。
解説記事はたくさんありますが、 @nuxtjs/axios の公式ドキュメントと内容がマッチしていなかったり、古かったりするので、自身で実装して確認したものを、自分の理解とともに記載します。

なお、@nuxtjs/axios モジュールを使わないほうが良いという認識はありますが、
今回直近の実装案件においては、そこまで開発規模が大きくなく、
自前実装すると逆にコードが増えるため、モジュールを使うことにしました。

そのうちモジュールを使わないパターンも書くかもしれませんが、
誰か書いていただけるとありがたいなーと思っています。

"@nuxtjs/axios": "^5.13.1"
"nuxt": "^2.15.5"

注意

target: 'static' のnuxtアプリでは、proxyは利用できません。
https://qiita.com/Yoshihiro-Hirose/items/520325f13dbb26f3f36f

参考資料

https://axios.nuxtjs.org/

前提

今回は外部APIのエンドポイントが、https://api.example.com/v1 だった場合で、
解説をしていきます。

また、リクエストを出す側の Nuxt アプリは、
http://localhost:3000 で起動しているとします。

Store (Vuex) から axios を使って外部APIを叩き、
取得したデータを state に格納します。

全体像の把握

今回の実装で全体的なリクエストの流れとしては、以下のようになります。

  1. this.$axios.get('/users') でリクエストを出す。
  2. axiosprefix オプションで、/api がつき http://localhost:3000/api/users にリクエストが出る
  3. /api がついているパスへのリクエストを proxy の対象として、target に指定したURL (https://api.example.com) + 2 のパス /api/userspathRewrite の指定が適応されて、 /api/v1 に変換される。
  4. 最終的に https://api.example.com/v1/users にリクエストが出る。

各ファイルの記述

nuxt.config.js

この実装は nuxt.config.js に正しく設定を記述できるかが肝です。

それさえできれば、各所でのリクエストの出し方は通常の @nuxtjs/axios の使い方です。

modules への追記と、別途 axios proxy の記述を行います。

{
  modules: [
    '@nuxtjs/axios',
  ],
  
  axios: {
    prefix: '/api',
    proxy: true,
  },

  proxy: {
    '/api/': {
      target: `https://api.example.com`,
      pathRewrite: {
        '^/api/': '/v1/',
      },
    },
  },

}

modules オプション

modules には '@nuxtjs/axios' だけの記述で良いです。
@nuxtjs/proxy'@nuxtjs/axios に含まれています。
実際記述しなくても動作します。

ただし、依存関係としてはインストールされている必要があります。

つまり要約すると、

  • modules に @nuxtjs/proxy の記述は不要
  • package.json@nuxtjs/axios は書かれている必要がある
  • @nuxtjs/proxy をあえて個別でアンインストールしたら動かないよ
    ということです。

以下公式の該当箇所。
https://axios.nuxtjs.org/options#proxy
Image from Gyazo

axios オプション

axios オプションの prefix によって、$axios.get などで行うリクエストには常に、
/api が自動で付与されるようになります。

// /api/users へリクエストになる
this.$axios.get('/users') 

axios オプションの proxytrue にします。
true にしないみたいな記事もありましたが、公式にするように書かれていますし、
実際 proxy: true を消すと、proxy は使われません。

注意

baseURL オプションを axios には設定しません。
公式に proxy を使う場合は、 baseURL は使えないとあります。

実際、間違って baseURL を設定している時うまく行かず、
外すと正常に動作しました。

proxy オプション

axios オプションにてプレフィックス /api を付けているので、
それを対象とするために、/api/: { オプション内容 } という記載になっています。

target に、外部APIのエンドポイントのホスト名までを指定します。

そして今回私のケースでは、外部APIには /v1 ついていますので、
pathRewrite で、/api/v1 に置き換えています。

しかし、特に /v1 などつかない場合は、
'^/api/': '', と記載します。

以上で、ほとんどの終わりです。

これで普通に this.$axios.get(...) などで、
外部APIを叩くことが出来ます。

store/***.js

以下は、特殊なことはなく store 内での普通の使い方です。
該当箇所だけ記述して、省略しています。

export const state = () => ({
  users: []
})

export const mutations = {
  add(state, data) {
    state.users = data
  }
}

export const actions = {
  async fetch({ commit, state }) {
    if (!state.users.length) {
      const res = await this.$axios.$get('/users')
      commit('add', res.data)
    }
  },
}

確認方法

nuxt コマンドを実行して、ローカルで起動した際に、
ターミナルに以下のように表示されていれば、設定できているということになります。

Image from Gyazo

Discussion