文件服务器
Golang标准库net/http
中提供了http.FileServer
方法会返回一个使用FileSystem
接口root
提供文件访问服务器的HTTP处理器,可方便地实现静态文件服务器。
http.ListenAndServe(":8080", http.FileServer(http.Dir("/files/path")))
-
http.Dir()
方法会返回http.Dir
类型用于将字符串路径转换为文件系统 -
http.FileServer()
方法返回的是fileHandler
实例,fileHandler
结构体实现了Handler
接口中的ServerHTTP()
方法。
对目录提供静态映射服务
http.Handler("/", http.FileServer(http.Dir("/tmp")))
使用http.FileServer
创建一个使用给定文件系统的内容响应所有HTTP请求的处理程序。
对文件提供静态映射服务
http.HandleFunc("/static/", func(rw http.ResponseWriter, rq *http.Rquest){
http.ServeFile(rw, rq, rq.URL.Path[1:])
})
支持子目录路径
- 可使用
http.StripPrefix()
方法配合http.Handle()
或http.HandleFunc()
实现待路由前缀的文件服务
http.Handle("/tmpfile/", http.StripPrefix("/tmpfile/", http.FileServer(http.Dir("/tmp"))))
静态资源服务器
- 支持客户端请求文件请求,将服务器磁盘上的静态文件直接响应给客户端。
例如:创建静态资源服务器
$ vim main.go
package main
import (
"net/http"
)
func main() {
//获取当前程序的运行目录
dir, _ := os.Getwd()
//创建公共资源目录
publicDir := path.Join(dir, "/public")
//创建静态资源目录
assetsDir := path.Join(publicDir, "/assets")
fmt.Println(assetsDir)
fmt.Printf("%s %T\n", assetsDir, assetsDir)
//创建给定文件系统的内容响应所有HTTP请求的处理程序
httpDir := http.Dir(assetsDir)
fmt.Printf("%s %T\n", httpDir, httpDir)
fs := http.FileServer(httpDir)
//让文件服务器使用assets目录下的文件响应URL路径以/static/开头的所有HTTP请求
//使用http.StripPrefix()方法将static前缀去掉后才能在assets目录下搜索请求的目标文件
handle := http.StripPrefix("/static/", fs)
//assets被设置为文件服务器的文件系统根目录
//文件服务器会处理以/static开头的URL的请求
http.Handle("/static/", handle)
//监听端口开启服务
http.ListenAndServe(":9000", nil)
}
服务端创建静态资源
$ vim /public/test.txt
hello test
客户端模拟请求访问静态资源
$ curl -i http://127.0.0.1:9000/static/test.txt
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 10
Content-Type: text/plain; charset=utf-8
Last-Modified: Mon, 15 Mar 2021 10:38:42 GMT
Date: Mon, 15 Mar 2021 10:39:34 GMT
hello test
http.FileServer
fs := http.FileServer(httpDir)
http.FileServer()
方法最终会返回一个fileHandler
结构实例
func FileServer(root FileSystem) Handler {
return &fileHandler{root}
}
fileHandler
结构拥有一个FileSystem
类型的root
属性,用于指定文件服务器的根。
type fileHandler struct {
root FileSystem
}
fileHandler
结构同时实现了Handler
接口的ServeHTTP()
方法,应该也是一个Handler
。
func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
upath := r.URL.Path
if !strings.HasPrefix(upath, "/") {
upath = "/" + upath
r.URL.Path = upath
}
serveFile(w, r, f.root, path.Clean(upath), true)
}
fileHandler
实现SererHTTP
的关键是serveFile()
函数
func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool)
http.StripPrefix
func StripPrefix(prefix string, h Handler) Handler
http.StripPrefix()
方法用于过滤指定处理程序对应请求的特定前序以显示出文件目录
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
StripPrefix()
方法返回一个处理器,该处理器会将请求的URL.Path
字段中给定前缀prefix
去除后再交给处理器来处理。若没有给定前缀存在则回复404页面未发现错误。
有疑问加站长微信联系(非本文作者)