Golang文件服务器为何无法刷新?

Golang文件服务器为何无法刷新? 我正在创建一个网站,并使用文件服务器来提供静态文件夹。问题是当我更改静态文件夹中的内容时,它不会更新。即使使用 go run <文件路径>.go 重启后也是如此。

以下是我的代码:

package main

import (
	"log"
	"net/http"
        /*内部导入*/
)

const Connection = "<设置sql连接字符串的临时方法,与此问题无关>"

func main() {
	http.HandleFunc("/", server.MainServe) /*server包含在内部导入中*/
        /*这里是更多的处理函数定义*/
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("<项目根目录>/web/static"))))
	/*第二个文件服务器,定义相同,问题也相同。*/
	log.Fatal(http.ListenAndServe(":8080", nil))
}

更多关于Golang文件服务器为何无法刷新?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

你所说的“不更新”是什么意思?

你是否记得禁用/清除浏览器缓存?

更多关于Golang文件服务器为何无法刷新?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你说得对。我没有禁用浏览器缓存。抱歉在这里发布了这个。

我使用Brave浏览器。隐私模式解决了我的问题。

我的意思是文件保留了它们旧的内容。例如,我修改了CSS,但浏览器看到的还是修改前的样子。

欢迎来到Web应用支持领域,这里60%的问题最终都只是浏览器缓存过于激进。另外40%则是那些谎称自己使用最新版Chrome,但实际上还在用Internet Explorer的人。wink

问题出在 http.FileServer 默认启用了缓存机制。当文件被首次请求后,服务器会发送 Cache-ControlETag 头,导致浏览器缓存静态资源。即使服务器重启,浏览器仍可能使用缓存的版本。

要解决这个问题,需要禁用或缩短缓存时间。以下是几种解决方案:

方案1:在开发环境中完全禁用缓存(推荐) 修改文件服务器处理程序,添加自定义的 Cache-Control 头:

package main

import (
	"log"
	"net/http"
	"time"
)

func main() {
	// 创建自定义的文件服务器处理器
	fs := http.FileServer(http.Dir("<项目根目录>/web/static"))
	
	// 包装文件服务器以添加禁用缓存的头部
	http.Handle("/static/", http.StripPrefix("/static/", 
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// 设置响应头禁用缓存
			w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
			w.Header().Set("Pragma", "no-cache")
			w.Header().Set("Expires", "0")
			
			// 调用原始的文件服务器
			fs.ServeHTTP(w, r)
		})))

	log.Fatal(http.ListenAndServe(":8080", nil))
}

方案2:使用时间戳或版本号强制刷新 在HTML中引用静态文件时添加版本参数:

<!-- 在HTML模板中 -->
<link rel="stylesheet" href="/static/css/style.css?v=1.0.0">
<script src="/static/js/app.js?t=20231225"></script>

方案3:开发环境使用实时重载工具 安装和使用 airfresh 等热重载工具,它们会自动检测文件变化并重启服务器:

# 安装 air
go install github.com/cosmtrek/air@latest

# 在项目目录中运行
air

方案4:生产环境设置合理的缓存策略 对于生产环境,应该设置适当的缓存时间,而不是完全禁用:

func main() {
	fs := http.FileServer(http.Dir("<项目根目录>/web/static"))
	
	http.Handle("/static/", http.StripPrefix("/static/", 
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// 设置缓存时间为1小时
			w.Header().Set("Cache-Control", "public, max-age=3600")
			fs.ServeHTTP(w, r)
		})))

	log.Fatal(http.ListenAndServe(":8080", nil))
}

方案5:使用 http.Dir 的包装器 创建一个自定义的文件系统实现,在每次请求时检查文件修改时间:

type noCacheFileSystem struct {
	fs http.FileSystem
}

func (nfs noCacheFileSystem) Open(name string) (http.File, error) {
	f, err := nfs.fs.Open(name)
	if err != nil {
		return nil, err
	}
	
	// 这里可以添加文件修改时间的检查逻辑
	// 或者强制重新读取文件的逻辑
	
	return f, nil
}

func main() {
	// 使用自定义的文件系统
	fs := http.FileServer(noCacheFileSystem{http.Dir("<项目根目录>/web/static")})
	
	http.Handle("/static/", http.StripPrefix("/static/", 
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Cache-Control", "no-cache")
			fs.ServeHTTP(w, r)
		})))

	log.Fatal(http.ListenAndServe(":8080", nil))
}

对于开发环境,建议使用方案1完全禁用缓存,配合方案3的热重载工具。对于生产环境,使用方案4设置合理的缓存策略。

回到顶部