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")