You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

过滤embed.FS导致HTTP服务器出现ERR_TOO_MANY_REDIRECTS错误如何解决

问题原因

核心冲突是http.FileServer的默认重定向逻辑和你自定义fs.FS实现的返回结果不匹配:

  • http.FileServer处理请求时,会先将URL路径转为文件系统的查询名称,再调用Open方法获取文件,随后通过Stat()方法判断返回的是目录还是文件。
  • 你实现的primaryFiles仅处理name="."的查询,当访问/index.html时,对应查询名称是index.html,你的实现直接返回fs.ErrNotExist,会触发FileServer的路径校正重定向逻辑。
  • 当访问/时,你返回的是index.html的文件句柄,其Stat()结果是文件而非目录,和/路径默认对应的目录属性冲突,导致FileServer计算重定向路径时逻辑异常,生成了..//这种错误的目标地址,最终引发循环重定向。
修复方案

这里提供两种实现简单的修复方式,按需选择即可:

方案1:单独处理根路径请求(更推荐,逻辑清晰无歧义)

不需要自定义fs.FS,直接为根路径编写单独的处理逻辑,仅在请求路径为/时返回index.html,其他根路径下的请求直接返回404:

package main

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

//go:embed index.html
var files embed.FS

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// 仅匹配根路径,避免匹配所有子路径
		if r.URL.Path != "/" {
			http.NotFound(w, r)
			return
		}
		// 直接读取embed的index.html返回
		content, err := files.ReadFile("index.html")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		w.Write(content)
	})
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(files))))
	log.Fatal(http.ListenAndServe(":8080", nil))
}

方案2:修正自定义fs的实现

如果你希望继续使用http.FileServer处理根路径,只需要扩展primaryFiles的Open逻辑,同时处理"."和"index.html"两个查询名称即可:

type primaryFiles struct {}

func (pf *primaryFiles) Open(name string) (fs.File, error) {
	switch name {
	case ".", "index.html":
		return files.Open("index.html")
	default:
		return nil, fs.ErrNotExist
	}
}

修改后/和/index.html都能正确返回内容,不会触发异常重定向。

内容的提问来源于stack exchange,提问作者flyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 19:24:05