はじめに
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対処が必要になったことを記載しました。
何かもっとスマートな対処があればよいのですが、ご存じの方がいらっしゃったら教えてください。
よろしくお願いいたします。