はじめに
SVGで画像というかアイコンを作ってみて、第2回ではimgタグにSVGファイルを入れて動作させてみました。
問題なく動作はしましたが、imgタグでは、SVGファイルに対してCSSが適用できないとう記事をいくつか見つけたため、imgタグ以外の方法を試すことにしました。
そうしたところ、CORSによる制限で、画像が表示されなくなりました。
そこで、CORSに対処するための方法があったため、記載をします。
CORSに対する対処は、SVGに特化したものでもないのですが・・・
今回実施する内容
作成したSVGファイルをHTMLファイルからSVGタグで読み込んだ場合、CORSによる制限で画像が表示されないため、その対処をまとめます。
ソースコード(Git Hub)
環境
OS: Windows 11 JP (64bit)
Edge: バージョン 130.0.2849.46 (公式ビルド) (64 ビット)
参考
用語
CORS
Cross-Origin Resource Sharing
オリジン間リソース共有。
オリジン(ホスト)が異なるリソースへのアクセスは禁止されることに対する対応のこと。
インターネットでは、様々な悪意あるサイトが存在するため、異なるサイトへの誘導を禁止するために、ブラウザにはアクセスを禁止する仕組みが導入されています。
事の始まり
「はじめに」に記載した通り、初めて作成したSVGファイルは、imgタグから設定して表示するようにしました(第2回 SVG ハンバーガーアイコン+hover)。
ですが、SVGファイルを動的にCSSなどで変化をつけるためには、imgタグではできないという記事がいくつかあり、ひとつの対処は、SVGをインラインで記載する(HTML内にsvgタグを使用して直接記載する)ことで対応できるようですが、それでは、HTML上の可読性は低くなりますし、汎用性も下がるため、好ましくはないと思いました。
もうひとつの対応として、svgタグを使用することと思い、svgタグを使用してみたところ、SVG画像が表示されなくなりました。
作成したSVG画像は第2回で作成したものだったため、何かおかしいと思って、ググってみて、SVGで読み込めない原因はヒットしなかったのですが、ちょっと違うところでCORSなのかなと思って、CORS対処をいれたところ動作したので、そうかなと思いました。
ローカル環境でのsvgタグを使ってみる
そのまま適用(画像が表示されない)した場合
<?xml version="1.0" standalone="no"?>
<svg id="humberGerIcon" width="32px" height="32px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" version="1.1">
<title>Example humberger icon</title>
<desc>Example humberger icon</desc>
<path d="M9 10 L24 10" stroke="black" stroke-width="2"/>
<path d="M9 16 L24 16" stroke="black" stroke-width="2" />
<path d="M9 22 L24 22" stroke="black" stroke-width="2" />
</svg>
humbergerIcon.svgは、第2回で作成したハンバーガーアイコンのSVGファイルとほぼ同じです。
1か所だけ、svgタグにid="humberGerIcon"を付与しました。
その他の説明は割愛します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>menu</title>
</head>
<body>
<svg width="64px" height="64px" viewBox="0 0 32 32">
<use xlink:href="humbergerIcon.svg#humbergerIcon"></use>
</svg>
</body>
</html>
menu.htmlもほとんど中身はありません。
svgタグで画像を表示しようと試みました。
svgタグ内は、width、heightで実際の大きさを指定して、viewBoxでビューのサイズを設定しました。
配下には、useタグを設定して、そこでhumbergerIcon.svg#humbergerIconを設定すれば、ハンバーガーアイコンが表示される想定でした。
ちなみに#humbergerIconはhumbergerIcon.svgのsvgタグで付与したidの値です。
CORS対処してみる(Visual Source Code (VSCode)編)
ソースの作成やデバッグにはVSCを使用しています。
VSCodeでは、起動時の設定をlaunch.jsonに記載をしますが、そこに手を入れました。
まずは、もとのlaunch.jsonからです。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "msedge",
"request": "launch",
"name": "Open menu.html",
"file": "c:\\03_SVGとCORS\\01_SVGタグ\\menu.html"
}
]
}
ここに、
"runtimeArgs": ["--disable-web-security", "--user-data-dir=${workspaceFolder}"]というのを加えます。
これをつけることで、VSCodeにおけるEdge起動時にCORSを無効にし、その対象のフォルダをworkspaceFolderに設定するってことです。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "msedge",
"request": "launch",
"name": "Open menu.html",
"file": "c:\\03_SVGとCORS\\01_SVGタグ\\menu.html",
"runtimeArgs": ["--disable-web-security", "--user-data-dir=${workspaceFolder}"]
}
]
}
これでVSCodeから「デバッグの開始」で実行してみると、以下の通り、ハンバーガーアイコンが表示されました。

「サポートされていないコマンドライン フラグ: --disable-web-securityを使用しています。これにより、安定性およびセキュリティに関するリスクが生じます。」というアラートも表示されました。
CORSを無効にしたことにより、安全ではないということを示すアラートのようです。
ローカル環境で実施しているため、この用途だけでEdgeを開いている分には問題にならないと思いますが、気持ちはよくないですね。
実際、ローカル環境でSVGを使用するときに常にこの状態で使用するのは、抵抗があるため、開発用途だけならと思いました。
また、これを実行すると、workspaceFolderに大量のファイルが作成されます。

これは、"--user-data-dir=${workspaceFolder}"ことによって、プロファイル情報が、workspaceFolder内に作成されたようです。
これも、とても気持ちの良いものではありませんので、やはり開発用途だけかなと思いました。
CORS対処してみる(コンソール編)
「CORS対処してみる(Visual Source Code (VSCode)編)」で、プロファイルが作成されたし、menu.htmlでEdge起動したらSVG表示されるかなと思いましたが、そんなことはなく、Edgeの起動設定は毎回必要なようです。
ということで、コマンドラインから
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --disable-web-security --user-data-dir="c:\\03_SVGとCORS" c:\\03_SVGとCORS\\01_SVGタグ\menu.html
な感じにすると、「CORS対処してみる(Visual Source Code (VSCode)編)」と同様の結果で、SVGファイルが表示されます。
ついでにユーザーが変わったせいで、Edgeの初期設定とかも始まってしまいましたが。
おわりに
今回はローカル環境でSVGファイルをsvgタグを使用して表示しようとしたところ、まさかのCORS対処が必要になったことを記載しました。
何かもっとスマートな対処があればよいのですが、ご存じの方がいらっしゃったら教えてください。
よろしくお願いいたします。
