5
5

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.

「No 'Access-Control-Allow-Origin'」が出た時に疑うこと・解決策リスト

Posted at

普段の環境

・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を作って、ミドルウェアに設定をしてあげるとよいです。

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') // ←アクセスを許可したいドメインを設定
            ->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」と打ち間違えた例。

typo.js
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」)
② 「閲覧履歴データの削除」
③ 「全期間」を選択、全部チェックで「データを削除」

image.png

これであっさり直るかも?

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の場合、こんな感じ。

main.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はつらいよ

また異なるケースが出れば追加していきます。

5
5
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
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?