CSS不生效,提示:Resource interpreted as Stylesheet but transferred with MIME type application/x-css
CSS不生效,提示:Resource interpreted as Stylesheet but transferred with MIME type application/x-css
初学Go语言如何实现一个Http Web服务器,于是在网上找了一个叫ChitChat的论坛的代码来研究,在调试的时候发现css不生效了,通过查看Chrome的开发者工具,发现Chrome提示了一个错误:Resource interpreted as Stylesheet but transferred with MIME type application/x-css。
上网查了该错误的原因,可以确定是由于浏览器请求css文件的时候,服务端返回的Content Type类型不是text/css,而是application/x-css,导致浏览器认为不正确,因此没有加载css文件进行渲染。
通过抓包也证实了该结论:
但是怎么能让Golang的Http web服务器返回text/css类型的Content Type呢?在网上搜索了很多文章,都没有涉及到这个问题。于是决定从代码入手来排查。先贴一段ChitChat处理Http请求的代码,如下:
代码使用了一个复用器,将请求css的URI中带有/static/的内容剥去,到config.Static配置对应的路径下去找对应的css资源(config.Static是在初始化从配置文件中读取的配置,配置文件中的值为"public")。例如网页中请求的URI为http://localhost:8888/static/css/bootstrap.min.css,程序就会到public/css目录下去找bootstrap.min.css资源。
css文件及其所在目录如下:
net/http对于访问静态文件资源大致的调用逻辑如下:
1)func (f *fileHandler) ServeHTTP
2)func serveFile
3)func serveContent
可以看到在serveContent函数中,是有对ContentType的相关处理的。
软件会根据文件扩展名,去获取content type,然后填写到报文头中。但这个文件扩展名和content type的关系是怎么来的呢?我们继续往后看,会注意到函数TypeByExtension的注释上有说明:原来在windows上,MIME类型是从注册表中来的。
那么css文件的类型又是在哪个注册表的键值中记录的呢?我们在golang的所有源码目录下搜索registry,会发现一个叫做mime\type_windows.go的源码文件,这应该就是我们需要找的地方了。
这个文件不长,我们很容易找到是在注册表CLASSES_ROOT根下找名为"Content Type"的键值。
于是我们在注册表中果然看到.css对应的值为"application/x-css",导致了错误的产生。
我们将该键值修改为"text/css",并重新清空浏览器缓存,重启后台服务,最终css可以正确显示了。
注:有时候清除浏览器还是不生效,观察下浏览器是否还有如下错误。"Provisional headers are shown"这个错误表示请求没有发上去,可能是因为缓存已经存在了导致。因此可以开个新窗口,然后把开发者工具打开,再请求几次看,直到没有出现错误。