第3回 SVG ローカル環境のCORS対処

# はじめに
SVGで画像というかアイコンを作ってみて、第2回では`img`タグにSVGファイルを入れて動作させてみました。
問題なく動作はしましたが、`img`タグでは、SVGファイルに対してCSSが適用できないとう記事をいくつか見つけたため、`img`タグ以外の方法を試すことにしました。
そうしたところ、CORSによる制限で、画像が表示されなくなりました。
そこで、CORSに対処するための方法があったため、記載をします。
CORSに対する対処は、SVGに特化したものでもないのですが・・・

# 今回実施する内容
作成したSVGファイルをHTMLファイルから`SVG`タグで読み込んだ場合、CORSによる制限で画像が表示されないため、その対処をまとめます。

# ソースコード(Git Hub)
https://github.com/Build-Mount/SVG_03_local_cors

# 環境
OS: Windows 11 JP (64bit)
Edge: バージョン 130.0.2849.46 (公式ビルド) (64 ビット)

# 参考
- [オリジン間リソース共有](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)

# 用語
## CORS
Cross-Origin Resource Sharing
オリジン間リソース共有。
オリジン（ホスト）が異なるリソースへのアクセスは禁止されることに対する対応のこと。
インターネットでは、様々な悪意あるサイトが存在するため、異なるサイトへの誘導を禁止するために、ブラウザにはアクセスを禁止する仕組みが導入されています。

# 事の始まり
「はじめに」に記載した通り、初めて作成したSVGファイルは、`img`タグから設定して表示するようにしました（[第2回 SVG ハンバーガーアイコン＋hover](https://qiita.com/Mount/items/7b4101afcd1c23ffb227)）。
ですが、SVGファイルを動的にCSSなどで変化をつけるためには、`img`タグではできないという記事がいくつかあり、ひとつの対処は、SVGをインラインで記載する（HTML内に`svg`タグを使用して直接記載する）ことで対応できるようですが、それでは、HTML上の可読性は低くなりますし、汎用性も下がるため、好ましくはないと思いました。
もうひとつの対応として、`svg`タグを使用することと思い、`svg`タグを使用してみたところ、SVG画像が表示されなくなりました。
作成したSVG画像は第２回で作成したものだったため、何かおかしいと思って、ググってみて、SVGで読み込めない原因はヒットしなかったのですが、ちょっと違うところでCORSなのかなと思って、CORS対処をいれたところ動作したので、そうかなと思いました。

# ローカル環境での`svg`タグを使ってみる
## そのまま適用（画像が表示されない）した場合
```html:humbergerIcon.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`は、第２回で作成したハンバーガーアイコンのSVGファイルとほぼ同じです。
１か所だけ、`svg`タグに`id="humberGerIcon"`を付与しました。
その他の説明は割愛します。

```html:menu.html
<!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`の値です。

しかし結果は、以下の通り空白だけでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/d638c320-16cb-a4c8-e4ea-82afaa7e42cf.png)

## CORS対処してみる（Visual Source Code (VSCode)編）
ソースの作成やデバッグにはVSCを使用しています。
VSCodeでは、起動時の設定を`launch.json`に記載をしますが、そこに手を入れました。
まずは、もとの`launch.json`からです。
```jsonc:修正前の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`に設定するってことです。

```jsonc:修正後の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から「デバッグの開始」で実行してみると、以下の通り、ハンバーガーアイコンが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/70c22eb4-c85e-b681-6a72-99cfacbde71b.png)

「サポートされていないコマンドライン フラグ： --disable-web-securityを使用しています。これにより、安定性およびセキュリティに関するリスクが生じます。」というアラートも表示されました。
CORSを無効にしたことにより、安全ではないということを示すアラートのようです。

ローカル環境で実施しているため、この用途だけでEdgeを開いている分には問題にならないと思いますが、気持ちはよくないですね。
実際、ローカル環境でSVGを使用するときに常にこの状態で使用するのは、抵抗があるため、開発用途だけならと思いました。

また、これを実行すると、`workspaceFolder`に大量のファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/254cdda4-8355-b3d7-4c03-8316cb9ee58c.png)
これは、`"--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対処が必要になったことを記載しました。
何かもっとスマートな対処があればよいのですが、ご存じの方がいらっしゃったら教えてください。
よろしくお願いいたします。