go处理静态资源,gin如何加载静态资源,beego如何加载静态资源
go处理静态资源
目录结构
D:\02_code\atest\staticfile>tree/f 卷 Data 的文件夹 PATH 列表 卷序列号为 D22A-BEC8 D:. ├─a1 │ main.go │ ├─a2 │ main.go │ ├─a3 │ main.go │ ├─a4 │ go.mod │ go.sum │ main.go │ └─static appendix.adoc config.properties favicon-16x16.png favicon-32x32.png gendoc.sh index.html oauth2-redirect.html swagger-ui-bundle.js swagger-ui-bundle.js.map swagger-ui-standalone-preset.js swagger-ui-standalone-preset.js.map swagger-ui.css swagger-ui.css.map swagger-ui.js swagger-ui.js.map swagger.json swagger.yml
原始方式
package main import ( "fmt" "io/ioutil" "log" "net/http" "net/url" "os" "path/filepath" "sort" "strconv" ) // 请求地址 http://localhost:8081/static/index.html func main() { mux := http.NewServeMux() mux.HandleFunc("/static/", fileHandler) server := &http.Server{ Addr: ":8081", Handler: mux, } if err := server.ListenAndServe(); err != nil { log.Fatal(err) } } func fileHandler(w http.ResponseWriter, r *http.Request) { path := ".." + r.URL.Path fmt.Println(path) f, err := os.Open(path) if err != nil { Error(w, toHTTPError(err)) return } defer f.Close() d, err := f.Stat() if err != nil { Error(w, toHTTPError(err)) return } if d.IsDir() { DirList(w, r, f) return } data, err := ioutil.ReadAll(f) if err != nil { Error(w, toHTTPError(err)) return } ext := filepath.Ext(path) if contentType := extensionToContentType[ext]; contentType != "" { w.Header().Set("Content-Type", contentType) } w.Header().Set("Content-Length", strconv.FormatInt(d.Size(), 10)) w.Write(data) } var extensionToContentType = map[string]string{ ".html": "text/html; charset=utf-8", ".css": "text/css; charset=utf-8", ".js": "application/javascript", ".xml": "text/xml; charset=utf-8", ".jpg": "image/jpeg", } func DirList(w http.ResponseWriter, r *http.Request, f http.File) { dirs, err := f.Readdir(-1) if err != nil { Error(w, http.StatusInternalServerError) return } sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() }) w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, "<pre>\n") for _, d := range dirs { name := d.Name() if d.IsDir() { name += "/" } url := url.URL{Path: name} fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), name) } fmt.Fprintf(w, "</pre>\n") } func toHTTPError(err error) int { if os.IsNotExist(err) { return http.StatusNotFound } if os.IsPermission(err) { return http.StatusForbidden } return http.StatusInternalServerError } func Error(w http.ResponseWriter, code int) { w.WriteHeader(code) }
http.FileServer
package main import ( "log" "net/http" ) // 请求地址 http://localhost:8081/static/ func main() { mux := http.NewServeMux() mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("../static")))) server := &http.Server{ Addr: ":8081", Handler: mux, } if err := server.ListenAndServe(); err != nil { log.Fatal(err) } }
http.ServeContent
package main import ( "flag" "log" "net/http" ) /* 启动命令:go run main.go -sd ../static/ 请求地址 http://localhost:8080/static/ */ var ( ServeDir string ) func init() { flag.StringVar(&ServeDir, "sd", "./", "the directory to serve") } func main() { flag.Parse() mux := http.NewServeMux() mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(ServeDir)))) server := &http.Server{ Addr: ":8080", Handler: mux, } if err := server.ListenAndServe(); err != nil { log.Fatal(err) } }
gin加载静态资源
package main // 导入gin包 import "github.com/gin-gonic/gin" // 请求地址 http://localhost:8080/static/ // 入口函数 func main() { router := gin.Default() // 设置静态资源文件目录,并且绑定一个Url前缀 // 静态资源文件目录:/var/www/tizi365/assets // /assets是访问静态资源的url前缀 // 例如: // /assets/images/1.jpg 这个url文件,存储在/var/www/tizi365/assets/images/1.jpg router.Static("/static", "../static") // 为单个静态资源文件,绑定url // 这里的意思就是将/favicon.ico这个url,绑定到./resources/favicon.ico这个文件 // router.StaticFile("/favicon.ico", "./resources/favicon.ico") //提示:设置/favicon.ico这个url,其实就是为网站设置图标,浏览器默认会将这个url作为网站默认图标。 // Listen and serve on 0.0.0.0:8080 router.Run(":8080") }
1.原始方式(IO文件)
原始方式的实现有一个缺点,实现逻辑复杂。上面的代码尽管我们已经忽略很多情况的处理了,代码量还是不小。自己编写很繁琐,而且容易产生 BUG。 静态文件服务的逻辑其实比较一致,应该通过库的形式来提供。为此,Go 语言提供http.FileServer
方法。
2.http.FileServer
mux.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./public"))))
http.FileServer
的返回值类型是http.Handler
,所以需要使用Handle
方法注册处理器。http.FileServer
将收到的请求路径传给http.Dir
的Open
方法打开对应的文件或目录进行处理。 在上面的程序中,如果请求路径为/static/hello.html
,那么拼接http.Dir
的起始路径.
,最终会读取路径为./static/hello.html
的文件。
http.StripPrefix
方法,该方法会将请求路径中特定的前缀去掉,然后再进行处理.
请求localhost:8080/static/hello.html
将会返回./public/hello.html
文件。 路径/static/index.html
经过处理器http.StripPrefix
去掉了前缀/static
得到/index.html
,然后又加上了http.Dir
的起始目录./public
得到文件最终路径./public/hello.html
。
3.http.FileServer
http.ServeContent
除了接受参数http.ResponseWriter
和http.Request
,还需要文件名name
,修改时间modTime
和io.ReadSeeker
接口类型的参数。
modTime
参数是为了设置响应的Last-Modified
首部。如果请求中携带了If-Modified-Since
首部,ServeContent
方法会根据modTime
判断是否需要发送内容。 如果需要发送内容,ServeContent
方法从io.ReadSeeker
接口重读取内容。*os.File
实现了接口io.ReadSeeker
。
参考:
https://darjun.github.io/2020/01/13/goweb/fileserver/
gin如何加载静态资源
1.通过io方式,用户请求读取文件,返回给用户,渲染界面。
2.和项目一起打包成二进制 ,bindata框架,更低的内存占用,依赖于reflect
和 unsafe
包。。
如果项目中包含js、css、jpg之类的静态文件,怎么访问访问静态文件?
func main() { router := gin.Default() // 设置静态资源文件目录,并且绑定一个Url前缀 // 静态资源文件目录:/var/www/tizi365/assets // /assets是访问静态资源的url前缀 // 例如: // /assets/images/1.jpg 这个url文件,存储在/var/www/tizi365/assets/images/1.jpg router.Static("/assets", "/var/www/tizi365/assets") // 为单个静态资源文件,绑定url // 这里的意思就是将/favicon.ico这个url,绑定到./resources/favicon.ico这个文件 router.StaticFile("/favicon.ico", "./resources/favicon.ico") //提示:设置/favicon.ico这个url,其实就是为网站设置图标,浏览器默认会将这个url作为网站默认图标。 // Listen and serve on 0.0.0.0:8080 router.Run(":8080") }
https://www.tizi365.com/archives/265.html
beego如何加载静态资源
//方式1: const env.WebStatic untyped string = "/mnt/web/static" beego.BConfig.WebConfig.StaticDir["/static"] = env.WebStatic //方式2: // 通过 /images/资源路径 可以访问static/images目录的内容 // 例: /images/user/1.jpg 实际访问的是 static/images/user/1.jpg web.SetStaticPath("/images","static/images") // 通过 /css/资源路径 可以访问static/css目录的内容 web.SetStaticPath("/css","static/css") // 通过 /js/资源路径 可以访问static/js目录的内容 web.SetStaticPath("/js","static/js")
本文作者:凌易说-lingyisay
本文链接:https://www.cnblogs.com/ling11/p/16591744.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律