Help us understand the problem. What is going on with this article?

type="module"がsafariで上手く読み込めなかった時の対応

More than 1 year has passed since last update.

概要

今まで何も考えず</body>前にJSを読み込ませてたのですが、最近のベストプラクティスとしてheadタグに

// モダンブラウザ用
<script type="module" src="js/main.js"></script>

// IE11などレガシーブラウザ用
<script nomodule src="js/nomodule.main.js" defer></script>

のように読み込むというプラクティスを発見し、実践した。
その際にsafariでのみ読み込みエラーが発生したため、その解決方法の備忘録です。

解説

type="module"での読み込みに関しては下記の記事の解説が分かりやすかったため
一読をおすすめします。
モダンブラウザに最適化した JavaScript を提供する
ライブラリ以外はとりあえず type="module" にしよう

nomoduleに関しては下記。
ES Modules への橋渡しとしての nomodule 属性

ひとまずざっくり説明すると、type="module"はモダンブラウザのために最適化された読み込み方式(deferとかでタイミング調整しなくても良い)で、type="module"に対応していないブラウザはnomoduleの方を自動的に読んでくれます。
逆に言えばnomodule"のJSはtype="module"対応ブラウザでは読み込まれないため、複数のpolyfillを読み込んで肥大化したファイルを読み込む必要がなくなります。便利。
なのでWebpackでそのあたりを出し分ければモダンブラウザで無駄のないJSファイルを配信できますね。

ハマったポイント

ここでタイトルの内容に入ります。
モダンブラウザに最適化した JavaScript を提供する
の記事内にありますが、type="module"でJSを読み込む場合、CROS通信(ざっくり言うと外部通信的な)扱いとなってしまい、MacOS、iOSのsafariでのみ
Blocked https://example.com/js/hoge.js from asking for credentials because it is a cross-origin request.
とアラートが出て読み込みができない問題が発生しました。

解決方法

ご紹介記事の中にもありますが、.htaccessなどサーバーサイドでAccess-Control-Allow-Origin: https://example.comのようにCROS通信を許可する方法があります。(セキュリティー上問題があるようなので、ワイルドカードでの指定はやめたほうが良さそう。)
ですが、実案件ではクライアントのサーバー設定をイジれないケースもあり、上記の方法では解決できませんでした。
また、Access-Control-Allow-Originの設定先を開発環境URLにしていて、公開したときに書き換え忘れて読み込めない!のような自体も想定できます。

いろいろ調べた結果、下記のように<script>タグにcrossorigin属性をつけることでサーバーサイドをイジる必要なく解決しました。

// crossorigin属性を追加
<script type="module" src="js/main.js" crossorigin="use-credentials"></script>

crossoriginの詳しい解説はこちら

crossorigin="anonymous"としても読み込みをされますが、こちらは実際に外部のCDNなどから読み込む場合に使用したほうが良さそう?なのでcrossorigin="use-credentials"としました。(『ちげぇよ馬鹿野郎!』というご指摘があれば教えていただけると助かります…)

shimooon
フロントエンドエンジニア
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした