Golang Web应用中如何隐藏目录列表

Golang Web应用中如何隐藏目录列表 我的应用程序具有以下结构: ~/go | |___ go二进制文件(或go源文件) | |___ static/css、static/js、static/images | |___ html/ 存放index.html、kit1.html等文件的位置

这原本工作正常,但用户可以指向http://mysite/static并获取目录列表,我想阻止这种情况。

我找到了一个关于如何规避此问题的示例。尝试对其进行调整:

func main() {
	//fs := http.FileServer(http.Dir("static/"))    (旧的可用版本)


	http.HandleFunc("/", indexHandler)
	http.HandleFunc("/kit1", indexHandler)

	fs := justFilesFilesystem{http.Dir("")}
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(fs)))
	log.Fatal(http.ListenAndServe(":8090", http.FileServer(fs)))
}

type justFilesFilesystem struct {
	fs http.FileSystem
}

func (fs justFilesFilesystem) Open(name string) (http.File, error) {
	f, err := fs.fs.Open(name)
	if err != nil {
		return nil, err
	}
	return neuteredReaddirFile{f}, nil
}

type neuteredReaddirFile struct {
	http.File
}

func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) {
	return nil, nil
}

我的处理程序以以下内容开始:

func indexHandler(w http.ResponseWriter, r *http.Request) { path, err := filepath.Abs(filepath.Dir(os.Args[0])) // 错误检查已省略

switch r.Method {
case "GET":
	f := urlToFile(r.URL.Path)
	fmt.Println("f: ", f)
	if f == "" {
		f = "index.html"
	}
	fmt.Println("f_after: ", f)
	http.ServeFile(w, r, "html/"+f)

虽然它似乎加载了大约150Kb的内容,但只显示一个空白页面,仅包含:

<pre>
</pre>

如果将index.htmlhtml/index.html复制到/home/lupe/go/,服务器会渲染它。

我不想更改htmlstatic文件的位置,应该对代码进行哪些修改?


更多关于Golang Web应用中如何隐藏目录列表的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

当选择/index.html/kit1.html时,函数indexHandler似乎没有被调用。

更多关于Golang Web应用中如何隐藏目录列表的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于你使用了自定义的 justFilesFilesystem 来包装根目录 "",这导致文件服务器从应用程序的当前工作目录开始提供文件,而不是从 static/ 目录。此外,你在 http.ListenAndServe 中使用了 http.FileServer(fs) 作为处理器,这会覆盖之前注册的路由。

以下是修正后的代码:

func main() {
    // 为静态文件创建自定义文件系统,禁用目录列表
    fs := justFilesFilesystem{http.Dir("static/")}
    
    // 注册路由
    http.HandleFunc("/", indexHandler)
    http.HandleFunc("/kit1", kit1Handler)
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(fs)))
    
    // 使用默认的ServeMux,不要用FileServer包装
    log.Fatal(http.ListenAndServe(":8090", nil))
}

type justFilesFilesystem struct {
    fs http.FileSystem
}

func (fs justFilesFilesystem) Open(name string) (http.File, error) {
    f, err := fs.fs.Open(name)
    if err != nil {
        return nil, err
    }
    return neuteredReaddirFile{f}, nil
}

type neuteredReaddirFile struct {
    http.File
}

func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) {
    // 返回空切片和nil错误来禁用目录列表
    return nil, nil
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    
    f := urlToFile(r.URL.Path)
    if f == "" {
        f = "index.html"
    }
    
    http.ServeFile(w, r, "html/"+f)
}

func kit1Handler(w http.ResponseWriter, r *http.Request) {
    if r.Method != "GET" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    http.ServeFile(w, r, "html/kit1.html")
}

// 假设的urlToFile函数示例
func urlToFile(path string) string {
    if path == "/" {
        return "index.html"
    }
    // 简单的路径到文件映射
    return strings.TrimPrefix(path, "/") + ".html"
}

关键修改:

  1. justFilesFilesystem 包装 http.Dir("static/") 而不是 http.Dir("")
  2. http.ListenAndServe 中移除 http.FileServer(fs),使用 nil 来默认使用已注册的处理器
  3. 添加了适当的错误处理和方法检查

这样配置后:

  • 访问 http://mysite/static/ 将返回404而不是目录列表
  • 静态文件仍然可以通过 http://mysite/static/css/style.css 等路径正常访问
  • HTML文件从 html/ 目录正确提供

确保你的目录结构保持为:

.
├── static/
│   ├── css/
│   ├── js/
│   └── images/
├── html/
│   ├── index.html
│   └── kit1.html
└── 你的Go程序
回到顶部