2020年7月26日日曜日

Vue + axios で CORS 対応を簡単にする方法

概要

一番手っ取り早いのはプロキシ機能を使うことです
ただしプロダクション用のビルド環境では使えないので注意が必要です

環境

  • macOS 10.15.6
  • nodejs 14.5.0
  • yarn 1.22.4
  • vue cli 4.4.6
  • vuetify (vue-cli-plugin-vuetify) 2.0.7
  • vue-axios 2.1.5

エラーの内容

こんな感じでブラウザに怒られます
サーバ側で対応してくれるのであればアプリ側は特に対応の必要はないですがそれでも開発時などは localhost で開発することが多いのでエラーに遭遇することが多いかなと思います

Access to XMLHttpRequest at 'https://kaka-request-dumper.herokuapp.com/' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

対応策

プロキシ機能というのがあるのでこれを使います

まず vue.config.jsdevServer.proxy という項目を追加します
ここにアクセス時に CORS エラーになった URL を記載します
最後の / スラッシュは記載しません

  • vim vue.config.js
module.exports = {
  transpileDependencies: ["vuetify"],
  devServer: {
    proxy: "https://kaka-request-dumper.herokuapp.com"
  }
};

あとは axios を使って呼び出す際にアクセスする URI の部分だけ指定するようにします
するとすべてのリクエストは一度プロキシを経由してアクセスするようになるため CORS エラーが発生しなくなります

  • vim src/components/HelloWorld.vue
<template>
  <v-container>
    <v-row>
      <v-col>
        <button v-on:click="getRequest">{{ button.name }}</button>
      </v-col>
    </v-row>
    <v-row>
      <v-col>
        <div>path_info: {{ path_info }}</div>
        <div>method: {{ method }}</div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",

  data: () => ({
    button: {
      name: "Get data"
    },
    path_info: "",
    method: ""
  }),
  methods: {
    getRequest: function() {
      this.axios
        .get("/api")
        .then(
          response => (
            (this.path_info = response.data.path_info),
            (this.method = response.data.method)
          )
        )
        .catch(err => console.log(err));
    }
  }
};
</script>

root はプロキシしてくれない?

ただこの方法を使う問題点として root パスはプロキシしてくれないっぽいです
https://github.com/vuejs/vue-cli/issues/3588

例えば .get("/") はプロキシしてくれません (もしかすると実現できる 方法があるかもしれないのですが自分はできませんでした)
具体的にどのような挙動になるかというと Vue アプリの root パスにアクセスするので作成しているアプリや UI の HTML が返ってきてしまいます
おそらく publicPath が影響しているのかなと思います

yarn build で作成したプロダクション用のソースではプロキシしてくれない

yarn build すると SAP 用の html, js, css が出力されます
完全にブラウザのみで動作するアプリになるのでプロダクション環境ではサーバ側に CORS 対応を入れてもらうしかありません
今回紹介した方法はあくまでも開発環境で使用するテクニックになります

最後に

Vue のプロキシ機能を使って CORS 対応してみました
簡単に CORS 対応できるので特に細かい仕様を気にしないのであればこれを使って良いかなと思います
ただ root パスはプロキシしてくれないのでそこだけ注意が必要かなと思います

参考サイト

0 件のコメント:

コメントを投稿