プログラマー VTuber 衣亥栖ティオのちょっとした話

Youtubeに投稿したプログラミング学習動画の補足説明をするためのブログです。

プログラマーへの道 #68 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。
今回は以下の動画の補足説明をします。 動画内で実装したソースコードも載せています。


今回の動画で実装したソースコード

前回からの差分は以下のURLから検索することができます。 "プログラマーへの道" の動画番号を "Filters" に追加して検索してください。

https://github.com/tio-iis/sample-backend-server/pulls?q=is%3Apr+is%3Aclosed

f:id:iis_tio:20211204143415j:plain:w300

全体は以下のURLのタグ検索機能で確認することができます。 "プログラマーへの道" の動画番号を "Find a tag" に指定して検索してください。

https://github.com/tio-iis/sample-backend-server

f:id:iis_tio:20211204143619j:plain:w300

動画内で発生したエラーの解消について

前回の動画で以下のエラーが発生しました。

Access to XMLHttpRequest at 'http://localhost:8080/get' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

このエラーは CORS という仕組みによって発生したエラーです。 CORSの説明は以下です。

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

これはざっくりいうと "バックエンドサーバのURLのドメイン" と "index.htmlを表示するドメイン" が同じでなければいけないというルールです。 今回の動画ではindex.htmlをわざわざバックエンドサーバから出力して、http://localhost:8080/getindexhtml でアクセスできるようにしました。 これはバックエンドサーバが提供するURLが http://localhost:8080/get, http://localhost:8080/countup のように "http://localhost:8080" に紐づくものだからです。 エラーが発生したときの index.html のURLは http://localhost:8080 ではなく、 以下の画像にある通りWindows PC上のファイルパスでした。

f:id:iis_tio:20211211185642j:plain

index.htmlの読み込み方法について

バックエンドサーバにindex.htmlを読み込む実装は以下です。 getIndexHTML() という関数内でファイルを読み込んでいます。

func getIndexHTML(w http.ResponseWriter, r *http.Request) {
    data, err := os.ReadFile("index.html")
    if err != nil {
        fmt.Fprintln(w, "can't read the file")
        return
    }

    fmt.Fprintln(w, string(data))
}

一方でメモ帳アプリのバックエンドサーバであるmemo-serverのファイル読み込みは以下のようにmain()の中で実行しています。

https://github.com/tio-iis/memo-server/blob/tag65/main.go#L15-L21

なぜ今回のファイル読み込みとメモ帳アプリのバックエンドサーバのファイル読み込みの定義場所が異なるのかというと、 ファイル読み込みをmain()の中で実行してしまうと、index.htmlを修正するたびにバックエンドサーバを再起動しなければいけないからです。 main()はサーバ起動時に一度しか実行されないので、起動後にindex.htmlを修正してもその修正が反映されません。

getIndexHTML() はHTTPリクエストを送るたびに実行される(ファイルを読み直す)ので、バックエンドサーバを起動したあとにindex.htmlを修正したとしても、サーバの再起動なしでその修正が反映されます。 開発時は通信部分のサンプル実装をするということなので、index.htmlのみを修正する機会がありました。 そのたびに毎回サーバを再起動するのが面倒だったので、getIndexHTML()内でファイルを読み込んでいます。