👾
Go言語でHTMLのファイルを表示してみた
挨拶するだけのHTMLを表示する
これだけなら簡単ですね。今回は、echoというフレームワークを使って、HTMLのファイルを表示してみようと思います。
echoの環境構築はこちらの記事が参考になると思います
🏠HTMLのファイルを用意する
/helloのURLにアクセスすると表示されるページ
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
background-color: #eee;
}
.container {
text-align: center;
font-size: 50px;
color: #666;
}
</style>
<title>Document</title>
</head>
<body>
<div class="container">
<h1>Hello Go!</h1>
</div>
</body>
</html>
404 Not Foundのページを返すHTMLファイル。存在しないURLにアクセスすると表示されます。
404.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>404 Not Found</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f1f1f1;
margin: 0;
}
h1 {
font-size: 3rem;
color: #666;
text-align: center;
}
p {
font-size: 1.5rem;
color: #666;
text-align: center;
}
</style>
</head>
<body>
<h1>404 Not Found</h1>
</body>
</html>
🦍Goのコード
Hello Worldのメッセージを変えるAPIと、プロジェクト内に配置したhtmlのファイルを表示するコードです。404.htmlだけは、特殊で存在しないURLにアクセスしたときだけ表示されます。
server.go
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
// 404ページを表示する関数を実行
e.HTTPErrorHandler = customHTTPErrorHandler
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
// /helloのURLにアクセスしたら、Hello GolangというHTMLを返す
e.GET("/hello", getGreet)
e.Logger.Fatal(e.Start(":1323"))
}
// h1タグでHello Golangと表示するHTMLを返す
func getGreet(c echo.Context) error {
return c.File("index.html")
}
// 404ページを表示する関数
func customHTTPErrorHandler(err error, c echo.Context) {
code := http.StatusInternalServerError
message := http.StatusText(code)
if he, ok := err.(*echo.HTTPError); ok {
code = he.Code
message = he.Message.(string)
}
if code == http.StatusNotFound {
// 404エラーの場合は404.htmlを返す
c.File("404.html")
return
}
c.JSON(code, map[string]interface{}{
"error": map[string]interface{}{
"code": code,
"message": message,
},
})
}
URLにアクセスしてみる
Hello Goのページ
存在しないページのURL
最後に
GoはAPIを作るための言語で、本来はHTMLを表示してテンプレートエンジンを使うような使い方ではないです。もし、Webアプリを作る場合は、Next.js、Reactで作ることになるでしょう。
Next.jsでHTTP通信したら、CORSのエラーにハマりました!
パッケージの追加と、コードの修正をしたら、できました!
私の場合はこれを追加した
go get github.com/labstack/echo/v4@v4.1.17
コードを修正する
package main
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" // <-- 追加
)
func main() {
e := echo.New()
// CORSを許可する
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowMethods: []string{echo.GET, echo.PUT, echo.POST, echo.DELETE},
}))
// 404ページを表示する関数を実行
e.HTTPErrorHandler = customHTTPErrorHandler
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
// /helloのURLにアクセスしたら、Hello GolangというHTMLを返す
e.GET("/hello", getGreet)
// /api/helloのURLにアクセスしたら、Hello GoというJSONを返す
e.GET("/api/hello", getHello)
e.Logger.Fatal(e.Start(":1323"))
}
// h1タグでHello Golangと表示するHTMLを返す
func getGreet(c echo.Context) error {
return c.File("index.html")
}
// Hello GoのJSONを返す関数
// Hello GoのJSONを返す関数
func getHello(c echo.Context) error {
dummyData := []map[string]interface{}{
{
"id": 1,
"message": "Hello Go",
},
{
"id": 2,
"message": "Hello again, Go",
},
{
"id": 3,
"message": "Hello once more, Go",
},
}
return c.JSON(http.StatusOK, dummyData)
}
// 404ページを表示する関数
func customHTTPErrorHandler(err error, c echo.Context) {
code := http.StatusInternalServerError
message := http.StatusText(code)
if he, ok := err.(*echo.HTTPError); ok {
code = he.Code
message = he.Message.(string)
}
if code == http.StatusNotFound {
// 404エラーの場合は404.htmlを返す
c.File("404.html")
return
}
c.JSON(code, map[string]interface{}{
"error": map[string]interface{}{
"code": code,
"message": message,
},
})
}
Next.jsのコード
Next.js13からは、appディレクトリなるものに変わったので、use client
をつけないとサーバーサイドコンポーネントになるそうです!
'use client';
import { useState, useEffect } from "react";
interface Hello {
id: number;
message: string;
}
const APIPage = () => {
const [hello, setHello] = useState<Hello[]>([]);
useEffect(() => {
const url = "http://localhost:1323/api/hello";
fetch(url)
.then((res) => res.json())
.then((json) => {
setHello(json);
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<div>
<ul>
{
hello.map((h, index) => (
<li key={index}>
{h.id} {h.message}
</li>
))
}
</ul>
</div>
);
}
export default APIPage;
コンポーネントを読み込む
import Counter from "./client/Counter";
import APIPage from "./client/Fetch";
export default function Home() {
return (
<div>
<APIPage />
</div>
);
}
実行結果
配列のデータを取得して、UIに表示できました🙌
コンソール見ると、エラーが出てるのでまだ改良が必要そうです。今回はこれでOK
Discussion