golang http.FileServer() 中列出错误链接的目录

And*_*llo 3 url http fileserver go

http.FileServer在 Go 中使用将一些静态文件提供到目录中。

这是我使用 mux 作为路由器来映射它的方式:

r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET")
Run Code Online (Sandbox Code Playgroud)

其中dirPath是我的文件系统中目录的绝对路径。

现在,当使用 localhost:8080/download 询问目录列表时,它似乎工作正常,因为它返回这样的页面

<pre>
<a href="a.xml">a.xml</a>
<a href="b.xml">b.zip</a>
</pre>
Run Code Online (Sandbox Code Playgroud)

不幸的是,这些链接已损坏,因为我希望将它们映射到例如localhost:8080/download/a.xml,而文件服务器将它们映射到localhost:8080/a.xml

如何使我的目录列表/download在链接中保留路径前缀?

icz*_*cza 6

问题是您注册处理程序的模式:"/download"

它有两个问题:

  1. 生成的 URL 是错误的,因为函数返回的http.FileServer()处理程序生成了文件和子文件夹的相对URL;相对于传递给的根文件夹http.FileServer(),如果您的页面在该路径下可用/download,则类似的相对 URLhref="a.xml"将被解析为/a.xml,而不是/download/a.xml

  2. 即使 URL 很好,文件也不会被提供,因为请求不会被路由到您的处理程序(文件服务器处理程序)。您必须添加尾部斜杠,因为"/download"仅匹配此单个路径,而不匹配以其开头的所有路径。添加尾部斜杠:"/download/"它将匹配根子树/download/*

所以解决办法是:

r.PathPrefix("/download/").Handler(
    http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")
Run Code Online (Sandbox Code Playgroud)

这记录在http.ServeMux

模式命名固定的根路径,例如“/favicon.ico”,或根子树,例如“/images/”(注意尾部斜杠)。

请注意,即使我们现在使用"/download/"注册的路径,用户也不需要在浏览器中键入尾部斜杠,因为将其省略,服务器将发送重定向到以尾部斜杠结尾的路径。这会自动发生。这也记录在http.ServeMux

如果子树已注册,并且收到命名子树根但不带尾部斜杠的请求,则 ServeMux 会将该请求重定向到子树根(添加尾部斜杠)。可以通过单独注册不带尾部斜杠的路径来覆盖此行为。例如,注册“/images/”会导致 ServeMux 将对“/images”的请求重定向到“/images/”,除非“/images”已单独注册。

阅读相关问题:Go Web 服务器自动重定向 POST 请求

这是一个仅使用标准库的简单文件服务器应用程序:

http.Handle("/dl/",
    http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))),
)
panic(http.ListenAndServe("localhost:8080", nil))
Run Code Online (Sandbox Code Playgroud)