20

golang取代nginx布置前端项目(vue),mime问题,Resource interpreted as Stylesheet...

 3 years ago
source link: https://studygolang.com/articles/29665
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言:某些原因,想直接使用go编译生成的可执行文件+前端编译好的静态文件,直接布置项目,不用依赖于nginx。

想看结果的同学直接拉到最下面看代码和总结

开始探索:

首先想到的是golang路由中指向静态资源

知识点:http中的ServeFile方法和FileServe,这两个很像,这里使用第一个,区分自己去查,这个一般

只需要在你的HandlerFunc中指向你的资源地址,就可以反馈,这里本地使用了一个测试html,结果没问题

http.ServeFile(w, r, "./test.html")

你以为成功了,不不不,实际布置后马上给你出问题了

正式环境是这样的,因为静态资源放在同一级目录

http.ServeFile(w, r, "./dist/index.html")

问题发现(出现新问题):

访问地址,啥也没有~~~,检查问题,发现

eEvY3a.png!web

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显示啊~~~~,排除

RjQN3y7.png!web

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资源错误)~~~

vURJZnV.png!web

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
    }

测试了一下,居然成功了,哇哇哇哇,哈哈哈哈哈

iQZnyaY.png!web

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知识

FveQFjN.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK