我有点困惑许多示例显示了以下两者的用法:http.ServeFile(..)和http.FileServer(..),但似乎它们具有非常接近的功能.此外,我还没有找到有关如何设置自定义NotFound处理程序的信息.
// This works and strip "/static/" fragment from path fs := http.FileServer(http.Dir("static")) http.Handle("/static/",http.StripPrefix("/static/",fs)) // This works too,but "/static2/" fragment remains and need to be striped manually http.HandleFunc("/static2/",func(w http.ResponseWriter,r *http.Request) { http.ServeFile(w,r,r.URL.Path[1:]) }) http.ListenAndServe(":8080",nil)
我试图读取源代码,他们都使用serveFile(ResponseWriter,* Request,FileSystem,string,bool)底层函数.然而,http.FileServer使用自己的ServeHTTP()方法返回fileHandler,并在提供文件之前做一些准备工作(例如path.Clean()).
主要区别在于http.FileServer有效地将HTTP前缀与文件系统进行了几乎1:1的映射.在纯英文中,它提供了一个完整的目录路径.和所有的孩子.
说你有一个名为/ home / bob / static的目录,你有这个设置:
fs := http.FileServer(http.Dir("/home/bob/static")) http.Handle("/static",http.StripPrefix("/static",fs))
您的服务器将接收请求. / static / foo / bar,并提供/ home / bob / static / foo / bar(或404)
相比之下,ServeFile是一个较低级别的助手,可以用于实现类似于FileServer的某些功能,或者实现您自己的路径可能潜在的,以及任何数量的事情.它只需要命名的本地文件,并通过HTTP连接发送.它本身不会提供一个完整的目录前缀(除非你写了一个类似于FileServer的一些查找的处理程序)
注意天真地提供文件系统是一个潜在的危险的事情(有可能的方法来突破根树),所以我建议,除非你真的知道你在做什么,请使用http.FileServer和http.Dir,因为它们包括检查确保人们不能脱离FS,而ServeFile没有.
附录您的第二个问题,如何做一个自定义的NotFound处理程序,不幸的是,不容易回答.因为这是从内部函数serveFile调用的,因为你注意到,没有超级容易的地方打破这个.有可能会有一些偷偷摸摸的事情,例如用你自己的ResponseWriter拦截响应,它拦截了404响应代码,但我会把这个练习留给你.