普段の環境
・Vue CLI(4系)
・Laravel(6系)
・XAMPP
・Vue ⇔ Laravel間はaxiosを使用
疑うこと・解決策リスト
1. レスポンスヘッダーに「Access-Control-Allow-~~~」を入れているか
Vue.jsとLaravelなどで開発を行う場合、フロントエンド・バックエンドのドメインが異なる場合もあるかと思います。
(例えば、Vue.js→「http://localhost:8080」、Laravel→「http://localhost:8001」など)
この場合、axiosなどで普通に通信しようとすると、タイトルのCORSエラーが出るので、レスポンスヘッダー(バックエンド側)で、下記のような記述をしてあげましょう。
header('Access-Control-Allow-Origin: http://localhost:8080'); // ←アクセスを許可したいドメインを設定
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH');
header('Access-Control-Allow-Headers: Content-Type');
Laravelの場合、下記のようなMiddlewareを作って、ミドルウェアに設定をしてあげるとよいです。
<?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') // ←アクセスを許可したいドメインを設定
->header('Access-Control-Allow-Credentials', 'true')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH')
->header('Access-Control-Allow-Headers', 'Content-Type');
}
}
2. リクエストしているURLが存在しているか
よくあるのが、タイポ(タイプミス)で、存在しないURLにアクセスしている場合です。
この場合も、タイトルの「No 'Access-Control-Allow-Origin'~」エラーが発生することがあります。
下記は「/api/contact/send-mail」とするところを、「/api/contct/send-mail」と打ち間違えた例。
const formData = new FormData();
formData.append("contact_data", JSON.stringify(this.contactData));
this.$axios
.post(`/api/contct/send-mail`, formData) // ← タイポ!
.then((response) => {
console.log(response);
if (response.data.status === 200) {
alert("送信しました?");
return;
} else {
alert("エラーが発生しました。");
return;
}
})
.catch((err) => {
console.log(err);
});
3. キャッシュを削除してみる
以前、これに数時間悩まされました。
例えば、上の「2.」で示したようにタイポで一度「No 'Access-Control-Allow-Origin'~」エラーを出してしまうと、問題箇所をいくら直しても同じエラーが出続けることがあります。
こんな時はどこが悪いのかそれ以上深追いせずに、一度キャッシュを全消去してみましょう。
やり方はChromeの場合、
① 履歴を表示。(Windowsの場合、ショートカットキーは「Ctrl + H」)
② 「閲覧履歴データの削除」
③ 「全期間」を選択、全部チェックで「データを削除」
これであっさり直るかも?
4. フロントエンド側のProxyを使ってみる
フロントエンド側にProxy機能があるのなら、それを使ってみるのも一手です。
CORSは要は、
・「a.com」⇔「b.com」
のように、ドメインが違う通信を行おうとすることでエラーが出ます。
これを、Proxy(代理機能)を使用することで、ドメインを偽装することができます。
つまり、Proxyが間に入って、
・「a.com」→「b.com(Proxyで偽装)」⇔「b.com」
という通信になることで、CORSエラーを回避します。
Vue.jsの場合、Proxyの設定はこちらを参考に。
5. axiosの「axios.default.withCridentials」設定を行っているか
フロントエンドとバックエンドの通信をaxiosで行っている場合、
「axios.default.withCridentials = true;」の設定をしていないと、
「No 'Access-Control-Allow-Origin' ~ 」エラーが出ることがあります。
Vue.jsの場合、こんな感じ。
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
//
import axios from 'axios'
//
// グローバル登録(axiosを使う時はいつでも「axios.defaults.withCredentials = true;」)
axios.defaults.withCredentials = true; // ← ココ
axios.defaults.xsrfHeaderName = "X-CSRF-Token";
//
//
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
CORSはつらいよ
また異なるケースが出れば追加していきます。