2021年版 Nuxt.js + axios (module) 外部API利用 CORS 回避
概要
Nuxt から 自前実装の外部APIを利用する際の実装について解説します。
解説記事はたくさんありますが、 @nuxtjs/axios の公式ドキュメントと内容がマッチしていなかったり、古かったりするので、自身で実装して確認したものを、自分の理解とともに記載します。
なお、@nuxtjs/axios モジュールを使わないほうが良いという認識はありますが、
今回直近の実装案件においては、そこまで開発規模が大きくなく、
自前実装すると逆にコードが増えるため、モジュールを使うことにしました。
そのうちモジュールを使わないパターンも書くかもしれませんが、
誰か書いていただけるとありがたいなーと思っています。
"@nuxtjs/axios": "^5.13.1"
"nuxt": "^2.15.5"
注意
target: 'static' のnuxtアプリでは、proxyは利用できません。
参考資料
前提
今回は外部APIのエンドポイントが、https://api.example.com/v1 だった場合で、
解説をしていきます。
また、リクエストを出す側の Nuxt アプリは、
http://localhost:3000 で起動しているとします。
Store (Vuex) から axios を使って外部APIを叩き、
取得したデータを state に格納します。
全体像の把握
今回の実装で全体的なリクエストの流れとしては、以下のようになります。
-
this.$axios.get('/users')でリクエストを出す。 -
axiosのprefixオプションで、/apiがつきhttp://localhost:3000/api/usersにリクエストが出る -
/apiがついているパスへのリクエストをproxyの対象として、targetに指定したURL (https://api.example.com) +2のパス/api/usersにpathRewriteの指定が適応されて、/api→/v1に変換される。 - 最終的に
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をあえて個別でアンインストールしたら動かないよ
ということです。
axios オプション
axios オプションの prefix によって、$axios.get などで行うリクエストには常に、
/api が自動で付与されるようになります。
// /api/users へリクエストになる
this.$axios.get('/users')
axios オプションの proxy は true にします。
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 コマンドを実行して、ローカルで起動した際に、
ターミナルに以下のように表示されていれば、設定できているということになります。


Discussion