内容简介:前言:某些原因,想直接使用go编译生成的可执行文件+前端编译好的静态文件,直接布置项目,不用依赖于nginx。知识点:http中的ServeFile方法和FileServe,这两个很像,这里使用第一个,区分自己去查,这个一般只需要在你的HandlerFunc中指向你的资源地址,就可以反馈,这里本地使用了一个测试html,结果没问题
前言:某些原因,想直接使用 go 编译生成的可执行文件+前端编译好的静态文件,直接布置项目,不用依赖于nginx。
想看结果的同学直接拉到最下面看代码和总结
开始探索:
首先想到的是golang路由中指向静态资源
知识点:http中的ServeFile方法和FileServe,这两个很像,这里使用第一个,区分自己去查,这个一般
只需要在你的HandlerFunc中指向你的资源地址,就可以反馈,这里本地使用了一个测试html,结果没问题
http.ServeFile(w, r, "./test.html")
你以为成功了,不不不,实际布置后马上给你出问题了
正式环境是这样的,因为静态资源放在同一级目录
http.ServeFile(w, r, "./dist/index.html")
问题发现(出现新问题):
访问地址,啥也没有~~~,检查问题,发现
image.png
这两句话:
Resource interpreted as Stylesheet but transferred with MIME type text/plain: "http://localhost:5001/css/app.5e843a4a.css". localhost/:1 Resource interpreted as Stylesheet but transferred with MIME type text/plain: "http://localhost:5001/css/chunk-vendors.43fc3011.css".
他说的大概意思是这个css解析的不对,直接变成文本传输的了,然后就发现mime这个是啥呢,查了一下资料,叫“多用途互联网邮件扩展类型”,就是文件类型解析的时候对应哪一个类型来解析,比如说这里,“.css”文件应该用“text/css”来解析,但是他用错了,所以变成了文本。
继续查资料。
看到了一句话,说是加一句
w.Header().Add("Content-Type", "text/plain")
这样不对,反馈的直接变成文本了,虽然错误没了,但是我要的是html显示啊~~~~,排除
image.png
问题发现,与mime相关(出现新问题)
终于,找到了原因,查阅相关资料得出,nginx有自己的mime文件,所以不会有问题,
使用go的程序执行时,调用的是系统的mime文件,可能会出现问题。
找到问题了,当然就知道怎么做了,直接搜索,golang mime,看看有没有解决办法,还真的有这个包“mime”,内容也简单,就几个函数,具体的就不说了,就说这里用到的。
func init() { mime.AddExtensionType(".js", "text/javascript") mime.AddExtensionType(".css", "text/css; charset=utf-8") }
在init中增加这个方法,意思是,告诉他,这个类型的文件,用后面这种方式去解析,别搞错了,他就知道了。继续测试,看看是否成功呢!
果然不出所料,还是不行(如果是线上服务器环境,这里可能会有404资源错误)~~~
image.png
问题解决(方法正确):
为什么呢,想不通~~~,继续查资料,擦查了好久都没有发现问题,突然,看到了这个路由,联想到刚刚出现的404,突然想到,方法是对了,可能资源路径不对吧。
http://localhost:3000/css/chunk-vendors.43fc3011.css
就像上面出现的这个路径,他肯定不对啊,肯定没有这个资源啊,怀着试一试的态度,调整一下自己的路由,加上下面这个代码
if paths[0] == "css" || paths[0] == "js" || paths[0] == "fonts" { str, err := os.Getwd() if err != nil { logrus.WithFields(logrus.Fields{"path": err.Error()}).Warn("getwd") return } http.ServeFile(w, r, filepath.Join(str, "dist", paths[0], paths[len(paths)-1])) return }
测试了一下,居然成功了,哇哇哇哇,哈哈哈哈哈
image.png
最后总结一下:
1.完整资源布置需要的几步
1.1.需要自己调节url的资源访问路径,并将它们用ServeFile指向你的index.html,css,js等资源(这一步很难想到,中间可能会有404的错误,不过只有正式线上才有,本地不会有,所以浪费了很多时间)
1.2.使用mime包,使得go程序可以正确解析静态资源文件类型
2.测试总代码(我这里vue生成的dist文件夹放在可执行文件同一级,你们需要注意自己的路径):
package main import ( "mime" "net/http" "net/url" "os" "path/filepath" "strings" "github.com/Sirupsen/logrus" ) func init() { mime.AddExtensionType(".js", "text/javascript") mime.AddExtensionType(".css", "text/css; charset=utf-8") } func main() { http.Handle("/", http.HandlerFunc(httpProcess)) http.ListenAndServe(":5001", nil) } func httpProcess(w http.ResponseWriter, r *http.Request) { if r.URL.String() == "/" { str, err := os.Getwd() if err != nil { logrus.WithFields(logrus.Fields{"path": err.Error()}).Warn("getwd") return } http.ServeFile(w, r, filepath.Join(str, "dist", "index.html")) //反馈静态主页,需要下面css,和js以及fonts的资源路径配合 return } paths, err := parsePaths(r.URL) //这里的path反馈工作元素内容待定 if err != nil { logrus.Error(err) w.WriteHeader(http.StatusBadRequest) w.Write(nil) return } if paths[0] == "css" || paths[0] == "js" || paths[0] == "fonts" { str, err := os.Getwd() if err != nil { logrus.WithFields(logrus.Fields{"path": err.Error()}).Warn("getwd") return } http.ServeFile(w, r, filepath.Join(str, "dist", paths[0], paths[len(paths)-1])) return } } //解析url func parsePaths(u *url.URL) ([]string, error) { paths := []string{} pstr := u.EscapedPath() for _, str := range strings.Split(pstr, "/")[1:] { s, err := url.PathUnescape(str) if err != nil { return nil, err } paths = append(paths, s) } return paths, nil } l
附录:还可以使用一个缩小包,来减少静态资源中的大小 github.com/tdewolff/minify
,就是这个,使用起来也简单,这里就不多说了
欢迎关注我们的微信公众号,每天学习Go知识
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 浙江:严禁用App布置作业
- 教育部:明确教师不得通过手机微信和QQ等方式布置作业
- 安全狗解读云等保:网络安全法是战略,等保规范是战术布置
- 如何在曲面上布置各种体块?建筑师编程指南之 SketchUp 插件开发(三)
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。