在 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"
。
它有两个问题:
生成的URL是错误的,因为http.FileServer()
函数返回的handler生成了relativeURLs到文件和子文件夹;相对于传递给 http.FileServer()
的根文件夹,如果您的页面在路径 /download
下可用,则像 href="a.xml"
这样的相对 URL 将被解析为 /a.xml
, 而不是 /download/a.xml
.
即使 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))
我在 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"
。
它有两个问题:
生成的URL是错误的,因为
http.FileServer()
函数返回的handler生成了relativeURLs到文件和子文件夹;相对于传递给http.FileServer()
的根文件夹,如果您的页面在路径/download
下可用,则像href="a.xml"
这样的相对 URL 将被解析为/a.xml
, 而不是/download/a.xml
.即使 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))