我在Go中使用http.FileServer
将一些静态文件提供到目录中。
这是我使用mux作为路由器映射的方式:
r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET")
其中dirPath
是我文件系统中目录的绝对路径。
现在使用localhost:8080 / download询问目录列表似乎工作正常,因为它返回这样的页面
<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
路径前缀?
答案 0 :(得分:2)
问题是您使用以下方式注册处理程序的模式:"/download"
。
它有两个问题:
生成的网址错误,因为http.FileServer()
函数返回的处理程序会为文件和子文件夹生成相对网址;相对于传递给http.FileServer()
的根文件夹,如果您的网页在/download
路径下可用,则href="a.xml"
之类的相对网址将被解析为/a.xml
,而不是/download/a.xml
。
即使URL很好,也不会提供文件,因为请求不会被路由到您的处理(文件服务器处理程序)。您必须添加一个尾部斜杠,因为"/download"
仅匹配此单个路径,而不是所有以它开头的路径。添加一个尾部斜杠:"/download/"
,它将匹配有根的子树/download/*
。
所以解决方案是:
r.PathPrefix("/download/").Handler(
http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")
记录在http.ServeMux
:
模式名称是固定的,有根的路径,如“/favicon.ico”,或有根的子树,如“/ images /”(请注意尾部斜杠)。
请注意,即使我们现在使用"/download/"
注册路径,用户也不需要在浏览器中键入尾部斜杠,因为将其留在服务器中会将重定向发送到以一个尾随斜线。这将自动发生。这也记录在http.ServeMux
:
如果已注册子树并且收到命名子树根但没有其斜杠的请求,则ServeMux会将该请求重定向到子树根(添加尾部斜杠)。可以覆盖此行为单独注册没有尾部斜杠的路径。例如,注册“/ images /”会导致ServeMux将“/ images”请求重定向到“/ images /”,除非“/ images”已单独注册。
阅读相关问题:Go web server is automatically redirecting POST requests
这是一个只使用标准库的简单文件服务器应用程序:
http.Handle("/dl/",
http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))),
)
panic(http.ListenAndServe("localhost:8080", nil))