1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Laravel × Vue CLIのCORS問題+セッション問題を解決した方法

Posted at

環境

・Laravel 6
・Vue CLI 3
・フロントエンドの開発は vue ui から立ち上げた「localhost:8080」
・データベースはXAMPPを使用
・Laravel ⇔ Vue 間の通信はaxiosを使用

結論

サーバーの用意

サーバーは以下の3つ用意します。
・Vueの開発用サーバー(localhost:8080)
・Laravel用のサーバー(localhost:8001)
・データベース用サーバー(XAMPPで「http://hoge.localhost」など)

それぞれの立ち上げ方は、

▶ Vueの開発用サーバー(localhost:8080)
「Windows + R」でコマンドプロンプトを開く
→「vue ui」(この時点でデフォルトで「localhost:8000」が立ち上がる)
→「タスク」
→「serve」
→「タスクの実行」
(もしくは「npm run serve」)
→おわり

▶ Laravel用のサーバー(localhost:8001)
「Windows + R」でコマンドプロンプトを開く
→Laravelのルートディレクトリまで移動
→「php -S localhost:8001」(「8001」の部分は他と被らなければなんでもOKです。)
→おわり

▶ データベース用サーバー(XAMPPで「http://hoge.localhost」など)
※割愛します。DBは好きなので立ち上げてください。

Vue側の準備

※「axios.defaults.withCredentials = true;」が大事!

main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'

//グローバル登録
axios.defaults.withCredentials = true;
axios.defaults.xsrfHeaderName = "X-CSRF-Token";
Vue.prototype.$axios = axios;

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
  // example.vue
  //
  ,
  computed: {
    ...mapGetters(["rootUrl"]) // store から getters で呼び出しています。「http://localhost:8001」(Laravel用のサーバー)が代入されます。
  },
  methods: {
    registerArticleData() {
      let params = new URLSearchParams();
      params.append("article_data", this.articleData);
      this.$axios
        .post(`${this.rootUrl}/api/article/register-article-data`, params)
        .then((response) => {
          console.log(response);
          if (response.data.status === 200) {
            alert("登録しました。");
            return;
          } else {
            alert("エラーが発生しました。");
            return;
          }
        })
        .catch((error) => {
          console.log(error);
        });
    }
  }

Laravel側の準備

下記のようなmiddlewareを用意して、Karnel.phpに登録します。

AccessControlAllow.php
<?php

namespace App\Http\Middleware\Api;

use Closure;

class AccessControlAllow
{
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', 'http://localhost:8080') // 「8080」は「Vueの開発用サーバー」に合わせましょう。
            ->header('Access-Control-Allow-Credentials', 'true')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH')
            ->header('Access-Control-Allow-Headers', 'Content-Type');
    }
}

以上!

これでCORSを上手く回避できた。
さらに、セッションも上手く引き継がれます。

proxyを試してみたけどダメだった件について

以前、Laravel × vite で開発をした時は、「vue.config.js」に以下のような記述をすればすんなりCORSを回避できました。

vue.config.js
module.exports = {
  //
    ,
    devServer: {
        proxy: {
            '^/api': {
                target: 'http://hoge.localhost', // Laravel用サーバーのアドレス(XAMPPで立ち上げてた)
                changeOrigin: true
            },
        }
    }
}

なので、今回も「前はCORSに苦しめられたけど、もうProxy使えば平気だもんね~♪」と思って試してみたら下記のようなエラー。
image.png

Proxy error: Could not proxy request /api/article/register-article-data from localhost:8080 to http://hoge.localhost (ENOTFOUND).

ここから数時間は格闘しましたよね~、
viteはできるのにVue CLIだとできない、この違いはいったい、、。

あなたはスタックしませんように。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?