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

Directory listing wrong links in golang http.FileServer()

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

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

r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET")

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

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

<pre>
<a href="a.xml">a.xml</a>
<a href="b.xml">b.zip</a>
</pre>

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

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

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

它有两个问题:

  1. 生成的URL是错误的,因为http.FileServer()函数返回的handler生成了relativeURLs到文件和子文件夹;相对于传递给 http.FileServer() 的根文件夹,如果您的页面在路径 /download 下可用,则像 href="a.xml" 这样的相对 URL 将被解析为 /a.xml , 而不是 /download/a.xml.

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

所以解决方案是:

r.PathPrefix("/download/").Handler(
    http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")

这记录在 http.ServeMux:

Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash).

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

If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.

阅读相关问题:

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

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