Go web端点找不到静态的index.html文件

huangapple go评论73阅读模式
英文:

Go web endpoint does not find static index.html file

问题

这是我的代码:

package main

import (
	"fmt"
	"log"
	"net/http"
)

const customPort = "3001"

func main() {
	fileServer := http.FileServer(http.Dir("./static"))
	port := fmt.Sprintf(":%s", customPort)
	http.Handle("/", fileServer)

	fmt.Printf("在端口%s上启动前端服务", port)
	err := http.ListenAndServe(port, nil)
	if err != nil {
		log.Panic(err)
	}
}

顶级文件夹是 microservices,设置为 Go 工作区。这个 Web 服务将是众多服务之一。它位于以下文件夹中:

microservices
 |--frontend
    |--cmd
       |--web
          |--static
             |--index.html
       |--main.go

我在顶级的 microservices 文件夹中,并使用 go run ./frontend/cmd/web 启动它。它没有错误地启动。但是当我在 Chrome 中输入 http://localhost:3001 时,显示 404 页面未找到。即使是 http://localhost:3001/index.html 也是 404 页面未找到。我正在学习 Go,不确定为什么它找不到 ./static 文件夹。

英文:

This is my code:

package main

import (
	"fmt"
	"log"
	"net/http"
)

const customPort = "3001"

func main() {
	fileServer := http.FileServer(http.Dir("./static"))
	port:= fmt.Sprintf(":%s", customPort)
	http.Handle("/", fileServer)

	fmt.Printf("Starting front end service on port %s", port)
	err := http.ListenAndServe(port, nil)
	if err != nil {
		log.Panic(err)
	}
}

The top level folder is microservices and is set up as a go workspace. This web service will be one of many services. It is in the following folder:

microservices
 |--frontend
    |--cmd
       |--web
          |--static
             |--index.html
       |--main.go

I am in the top level microservices folder, and I am starting it with: go run ./frontend/cmd/web. It starts up fine with no errors. But when I go to chrome and type http://localhost:3001 I get 404 page not found. Even http://localhost:3001/index.html gives 404 page not found. I am just learning go and not sure why it is not finding the ./static folder?

答案1

得分: 0

根据您的命令,路径应该是./frontend/cmd/web/static,而不仅仅是./static。这样不够可移植;路径会随着工作目录的改变而改变。

考虑嵌入静态目录。否则,您将不得不使路径可配置(标志、环境变量等)。

嵌入的缺点是,在静态文件发生任何更改后,您必须重新构建程序。

您还可以使用混合方法。如果设置了标志(或其他方式),则使用它来从磁盘提供服务,否则使用嵌入的文件系统。标志在开发过程中很方便,而嵌入的文件系统使部署变得容易,因为您只需复制程序二进制文件。

package main

import (
	"embed"
	"flag"
	"io/fs"
	"net/http"
	"os"
)

//go:embed web/static
var embeddedAssets embed.FS

func main() {
	var staticDir string

	flag.StringVar(&staticDir, "static-dir", staticDir, "Path to directory containing static assets. If empty embedded assets are used.")
	flag.Parse()

	var staticFS fs.FS = embeddedAssets
	if staticDir != "" {
		staticFS = os.DirFS(staticDir)
	}

	http.Handle("/", http.FileServer(http.FS(staticFS)))

	// ...
}
英文:

According to your command the path has to be ./frontend/cmd/web/static, not just ./static. That's not portable; the path changes with the working directory.

Consider embedding the static directory instead. Otherwise you'll have to make the path configurable (flag, environment variable, etc.)

The downside with embedding is that you have to rebuild your program after any change to the static files.

You can also use a hybrid approach. If the flag (or whatever) is set, use it to serve from disk, else use the embedded filesystem. The flag is convenient during development and the embedded filesystem makes deployment easy because you only have to copy the program binary.

package main

import (
	"embed"
	"flag"
	"io/fs"
	"net/http"
	"os"
)

//go:embed web/static
var embeddedAssets embed.FS

func main() {
	var staticDir string

	flag.StringVar(&staticDir, "static-dir", staticDir, "Path to directory containing static assets. If empty embedded assets are used.")
	flag.Parse()

	var staticFS fs.FS = embeddedAssets
	if staticDir != "" {
		staticFS = os.DirFS(staticDir)
	}

	http.Handle("/", http.FileServer(http.FS(staticFS)))

	// ...
}

huangapple
  • 本文由 发表于 2023年3月20日 01:19:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75783729.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定