http.FileServer在编辑后缓存文件并提供旧版本

onm*_*mon 11 http go

go的核心问题包有问题.虽然响应正文中的Content-Length是正确的,但似乎缓存了文件内容.这里演示的是我正在编写的应用程序的简化版本.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(http.Dir("./www/")))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个非常简单的html页面:

<!doctype html>
<html>
<body>
    <p>Hello there</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我执行go程序并http://localhost:8080在浏览器中访问以显示:

Hello there
Run Code Online (Sandbox Code Playgroud)

检查响应头我可以看到以下内容:

Status Code:200 OK
Accept-Ranges:bytes
Content-Length:68
Content-Type:text/html; charset=utf-8
Date:Fri, 20 Dec 2013 10:04:03 GMT
Last-Modified:Fri, 20 Dec 2013 10:03:32 GMT
Run Code Online (Sandbox Code Playgroud)

现在我编辑html文件,以便<p>标记包含Hello there everyone并重新加载页面.我得到以下内容:

Hello there
Run Code Online (Sandbox Code Playgroud)

再看一下我得到的响应头

Status Code:200 OK
Accept-Ranges:bytes
Content-Length:77
Content-Type:text/html; charset=utf-8
Date:Fri, 20 Dec 2013 10:04:34 GMT
Last-Modified:Fri, 20 Dec 2013 10:04:14 GMT
Run Code Online (Sandbox Code Playgroud)

因此,Content-Length已更改以及上次修改但不是http.FileServer处理程序提供的实际文件内容.即使关闭程序并执行此操作,也会发生此问题go run src/.../main.go.到目前为止,我发现清除文件的明显缓存版本的唯一方法是重新启动程序运行的机器.

我尝试过以下方法:

  • 在win/ubuntu/osx 10.8.5上执行程序
  • 浏览golang.org/src上的函数/接口链,看看服务文件是否在任何地方缓存在磁盘上

任何有关这方面的帮助将非常感激.

onm*_*mon 15

好的,所以在几个星期忽略了问题并继续前进后,我终于找出了问题所在.

为了让我的主计算机相当不自定,我使用Vagrant使用golang,nodejs和php开发应用程序.看起来在Virtual Box共享上运行go应用程序与该共享上存储的所有html文件会导致此问题.

为了证明这一点,我跨越了一个Vagrant框并将文件从/ vagrant共享目录复制到/ home/vagrant/testing /,然后复制了之前列出的所有操作.这使问题消失了.

换句话说,不要使用Virtual Box共享文件夹来托管打算在http.FileServer方法中使用的文件.

  • 这是VirtualBox的一个问题,并使用sendfile()(net/http内部使用),请参阅https://abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile/ (5认同)