事象
ググった時にもっと引っかかっても良いのになーと思いつつ、全然記事がヒットしなかったのでメモ。
Nuxt.jsでaxiosを使いAPIからデータを取得。
そのデータを元にページを表示している場合、URLを直接叩くと正常に表示されるが、nuxt-linkで遷移したりブラウザバックで移動するとAn error occurred
というエラーが出る。
結論
nuxt.config.jsで、axiosのproxyを設定しましょう。
理由
CORS(オリジン間リソース共有)が原因。
- URLを直接開いた時=SSR(サーバサイドレンダリング)が実行される。その名の通りサーバサイドで実行される。
- ブラウザバックやページ遷移=CSR(クライアントサイドレンダリング)が実行される。つまりクライアントのjsで実行されるので、CORSが関係してくる。
URL叩いた時に表示されるのであれば、APIのパスが誤っていたり処理がおかしいのではない。
サーバサイドとクライアントサイド、どちらで実行されているか気付けるかが鍵。
筆者は1時間以上悩みました
たとえ同じサーバ上で動いていても、バックエンドとフロントエンド(Nuxt)が違うportで動いていたら、CORSの対策が必要。
対処法
nuxt.config.js
** Nuxt.js modules
*/
modules: [
- "@nuxtjs/axios"
+ "@nuxtjs/axios",
+ "@nuxtjs/proxy"
],
+ axios: {
+ proxy: true
+ },
+ proxy: {
+ '/v1/': {
+ target: "https://example.com:8080/"
+ }
+ },
参考(API呼び出し):pages/posts/_id.vue
<script>
export default {
validate({ params }) {
return /^\d+$/.test(params.id)
},
async asyncData({ $axios, params }) {
const response = await $axios.$get(`/v1/posts/${params.id}`)
return {
post: response.post
}
}
}
</script>
-
@nuxtjs/proxy
はaxiosにセットで入っているので、yarn add不要です - /v1/の部分はお使いのAPIのパスに応じて変えてください。多くの場合、/api/になるはずです
- targetの部分はAPIのrootパスになるよう(必要だったらport番号も)適宜置き換えてください。