Golang http.ServeFile 处理静态文件contentType不正确
  • H5W3
  • 2021-07-07 18:14:03

我在用golang写http server,使用http.ServeFile来处理静态的文件,但是浏览器一直就是取不到正确的contentType 错误如下

Resource interpreted as Script but transferred with MIME type text/x-js: "http://127.0.0.1/:8080/public/js/jquery.js"

大致的代码如下:

func staticDirHandler(mux *http.ServeMux, prefix string, staticDir string, flags int) {

mux.HandleFunc(prefix, func(w http.ResponseWriter, r *http.Request) {

file := staticDir + r.URL.Path[len(prefix)-1:]

if (flags & ListDir) == 0 {

fi, err := os.Stat(file)

if err != nil || fi.IsDir() {

http.NotFound(w, r)

return

}

}

http.ServeFile(w, r, file)

})

}

主要是http.ServeFile 这个源码我也看了下,最后他调用了 serveContent里面有一段是进行文件的mime设置的。

	// If Content-Type isn't set, use the file's extension to find it.

129 ctype := w.Header().Get("Content-Type")

130 if ctype == "" {

131 ctype = mime.TypeByExtension(filepath.Ext(name))

132 if ctype == "" {

133 // read a chunk to decide between utf-8 text and binary

134 var buf [1024]byte

135 n, _ := io.ReadFull(content, buf[:])

136 b := buf[:n]

137 ctype = DetectContentType(b)

138 _, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file

139 if err != nil {

140 Error(w, "seeker can't seek", StatusInternalServerError)

141 return

142 }

143 }

144 w.Header().Set("Content-Type", ctype)

145 }

但结果确不是正确的,不知道该如何设置才能正确,另外我也看了golang.org 官网他本身也是有这个问题的,我使用的是chrome浏览器。

@小明 给出的回复之后,我发现单独访问,确实没有任何问题的,但是html调用就会出现,下面是我准备的测试例子,大家可以帮忙看下,问题出在哪里?

package main

import(

"fmt"

"net/http"

"io/ioutil"

"log"

)

func Handler( w http.ResponseWriter,r *http.Request ){

path := r.URL.Path[1:]

if path == "favicon.ico" {

http.NotFound(w, r)

return

}

if path == ""{

path = "index.html"

}

contents,err:= ioutil.ReadFile( path )

if err !=nil{

fmt.Fprintf( w,"404" )

return

}

fmt.Fprintf( w,"%s\n",contents )

}

func StaticServer(w http.ResponseWriter, req *http.Request) {

staticHandler := http.FileServer(http.Dir("./public/"))

staticHandler.ServeHTTP(w, req)

return

}

func main(){

http.HandleFunc( "/",Handler)

http.HandleFunc( "/public",StaticServer)

s := &http.Server{

Addr: ":8181",

}

log.Fatal(s.ListenAndServe())

}

index.html

<!DOCTYPE html>

<html>

<head>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<title>test page</title>

<link rel="stylesheet" href="public/css/base.css" type="text/css" />

</head>

<body>

<div id="container">

<header>

<h1>test page</h1>

</header>

<a class='save'>Save Now</a>

<section id="main-content">

<div class="form-area">

<form id="tasks-form">

<label for="task">Add a task here and hit enter</label>

<input id="task" autofocus="">

</form>

</div>

<ul id="tasks"></ul>

</section>

</div>

<li class="template" style="display:none">

<input type='checkbox'/>

<span >" "</span>

<a href=''>x</a>

</li>

<script type="text/javascript" src="public/js/jquery.js"></script>

<script type="text/javascript" src="public/js/base.js"></script>

</body>

</html>

单独访问js css都没有问题,但是访问html就会出现之前的那个警告提示了。我使用godoc --http=":8080" 本地访问也会有这个问题,你也可以测试下。

---------------------------------------------

最后在 “Go语言精英群” 的帮助下解决了。

原因是我系统的mime.type的问题,因为go语言使用的是系统的mime,像nginx是有自己的mime,所以不会有问题。

回答:

原因是我系统的mime.type的问题,因为go语言使用的是系统的mime,像nginx是有自己的mime,所以不会有问题。

/etc/mime.types

/etc/apache2/mime.types

/etc/apache/mime.types

所以如果用go写web服务最好准备一份mime.types

回答:

添加对应的mime就可以了

import mime

mime.AddExtensionType(".apk", "application/vnd.android")

回答:

http.ListenAndServe(":8080", http.FileServer(http.Dir("d:/test")))

处理静态文件,试试这样的看行不行。 我测试了下没问题

回答:

我遇到了和楼主一样的问题,请问楼主,最后找到是MIME的问题,但是怎么解决呢? 解决方法是什么?求助!

以上是 Golang http.ServeFile 处理静态文件contentType不正确 的全部内容, 来源链接: www.h5w3.com/182648.html