[Laravel] Font Awesomeが同一生成元ポリシーで読み込まれない時の対処法


初めてLaravelをデプロイした時Font Awesomeで少し詰まったのでメモ。

エラー内容

以下の記事を参考にLaravel Mixを利用してFont Awesomeを導入したけど、Herokuにデプロイしてみると本番環境のみFont Awesomeが読み込まれないエラーに遭遇。
https://readouble.com/laravel/5.8/ja/mix.html
https://qiita.com/algi_nao/items/5d2befae8f367050ae7f

エラー文には以下のような表示がされている。

ブラウザ(http://〜)から自サーバーに置いているフォントファイル(https://〜)を読み込む時にhttpとhttpsの違いによりクロスオリジンになってしまい、ブラウザ側でエラーが出ている。

なんでや(・_・?)

解決方法1

フォントファイルへアクセスするときはクロスオリジンを許可する方法。

Laravel Mixを使用した場合、以下のディレクトリにフォントファイルが格納されている。なので、このフォントファイルへのアクセスを許可してやればいい。

.htaccessファイルによってこのフォントファイル群へのクロスオリジンアクセスを許可します。
上記のfontsディレクトリ直下に.htaccessファイルを作成し、以下のように記述。

public/fonts/.htaccess
<FilesMatch "\.(ttf|svg|eot|woff|woff2)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>

拡張子を指定してフォントファイルへの制約を解除しています。
これを再デプロイすることでフォントファイルが読み込まれるはずです。

それでも表示されない場合は、ブラウザのキャッシュが残っていると表示されない場合があるので以下の記事を参考にキャッシュをクリア。
https://tekito-style.me/columns/laravel-css-changes#3_Laravel

解決方法2

httpsに統一してクロスオリジンにならないようにする方法。こちらの方が根本的な解決方法になる。

herokuは基本的にhttpsが有効になっているはずなのにアプリ内に生成されているリンクを見るとhttpになっている。
下のリンクではパスの生成にroute()を使っているが、生成されたパスがhttpになってしまっている。
そのため、リンクから遷移するとブラウザの表示がhttpになってしまい、クロスオリジンになってしまう。

参考記事によれば、以下のようにAppServiceProvider.phpに追記することで本番環境のみhttpsを強制することができる。

app/Providers/AppServiceProvider.php
    public function boot()
    {
       // 本番環境(Heroku)でhttpsを強制する
       if (\App::environment('production')) {
           \URL::forceScheme('https');
    }

これにより、生成されるリンクがhttpsになるためクロスオリジンではなくなりフォントファイルが読み込まれるはずです。

参考

ファイルを別ドメインから読み込ませようとしたら怒られた
XHR2でサブドメインのワイルドカードOriginに対してCORSを許可する設定、他。
Laravel5.7: Herokuにデプロイする