首页 > Golang http.ServeFile 处理静态文件contentType不正确

Golang http.ServeFile 处理静态文件contentType不正确

我在用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,所以不会有问题。
详细查看:http://golang.org/pkg/mime/#TypeByExt...


添加对应的mime就可以了

import mime

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

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


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

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


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

详细查看:http://golang.org/pkg/mime/#TypeByExt...

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

【热门文章】
【热门文章】