フリーランチ食べたい

No Free Lunch in ML and Life. Pythonや機械学習のことを書きます。

【Nuxt.js/axios】別ドメインへのajaxがCORS policyで弾かれる問題の対応

ここのところNuxt.jsで開発を行っていて、詰まったところがあったので記載しておきます。

TL;DR

  • 現状axios/devサーバーのヘッダー設定だけでは解決できません。(調べた限り)
  • devサーバー側でaxiosのproxyの設定を行う必要があります。

f:id:ikedaosushi:20190208230857p:plain

環境

  • vue@2.6.2
  • nuxt@2.4.2
  • axios@0.18.0

課題

問題設定をハッキリさせておきます。 下の図のようにローカルでの開発時にブラウザから外部のAPIサーバーにリクエストを送った際にCORS policyでブロックされてしまう問題です。

f:id:ikedaosushi:20190208233205p:plain

自分と同じ状況であれば

このようにアクセスしたときに

axios.get('http://api.example.com/hello')

下のようなエラーメッセージが出ていると思います。

Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://localhost.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

一般的には、localhostからのレスポンスのヘッダーに Access-Control-Allow-Origin をつければ解決しますが、下のIssueでかなり揉めているように簡単にはできないようです。

github.com

どう解決するか

解決方法としては、axiosのproxy機能を使ってdevサーバーでproxyを行うのが現状で最も良い解決策のようです。

nuxt.config.js

module.exports = {
  ... # 省略
  /*
  ** Nuxt.js modules
  */
  modules: [
    '@nuxtjs/proxy'
  ],
  proxy: {
    '/api/': { target: 'api.example.com', pathRewrite: {'^/api/': ''} }
  }
}

これだけでproxyの設定完了です。あとは下のようにリクエストを送れば当初行いたかったAPIアクセスが実現できます。

axios.get('http://localhost:3000/api/hello')

f:id:ikedaosushi:20190208234250p:plain

最後に

  • proxyはローカルで立ち上げているdevサーバーで行っているので、buildした場合はこのproxyは使えなくなるため、向き先を変えるか、サーバーで別途proxyの設定をする必要があります。
  • proxyの設定をするくらいなら、CORSの設定をした方が早い気がするので現実的にはそうなるのではないでしょうか。
  • Nuxt.js初心者なので、また詰まったところがあれば書いていこうと思います。