Golang中浏览器缓存的工作原理是什么?

Golang中浏览器缓存的工作原理是什么? 我的网站中有一些文件(.css、.js、.html)会经常变动,但同时还有许多其他文件(具有上述相同的扩展名)将始终保持静态,因此我想告诉浏览器哪些文件允许缓存。我该如何使用Go来实现这一点?

另一方面,我读到浏览器总是会缓存.html文件,如果这是真的,那么动态网站究竟如何工作呢?这将迫使大量使用JavaScript,并且不允许使用模板等技术。值得一提的是,我是在一些旧帖子中读到这些信息的,并且找不到当前的信息,但我的直觉告诉我,目前任何浏览器都会缓存.html文件,我的想法对吗?

12 回复

如果我告诉浏览器**(通过使用头部信息)**不要缓存.html文件

更多关于Golang中浏览器缓存的工作原理是什么?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


缓存很有用,但如果服务器端的内容发生变化,缓存就不那么有用了。

缓存将始终处于过时状态。

Sibert:

包含动态数据的静态页面

这正是我的情况,那么我需要担心浏览器缓存 .html 文件吗?

如果我那样做,HTML中的.css和.js文件会怎样?它们也会停止被保存到缓存中,还是它们与origin头部无关?

为满足您的标准,编写处理程序来为每个文件添加适当的缓存控制应该足够简单,例如:

if !thisFileShouldNotBeCached(file) {
  # 在此处设置缓存控制为不缓存
}

Willy:

这是我的情况,那么我应该担心浏览器缓存.html文件吗?

浏览器缓存页面是为了在你下次加载相同内容时提高速度。你在担心什么呢?通常缓存是件好事。因此我使用Cloudflare来进一步增加缓存……

哦,抱歉,我指的是客户端。如果我告诉浏览器不要缓存 .html 文件,那么 .css 和 .js 文件(它们是 .html 文件主体中的链接)会怎么样?我为 .html 文件在头部设置的规则是否也适用于它们,还是每个文件都是独立的?

通过你的 ResponseWriter 添加 Cache-Control 头部。

w.Header().Set("Cache-Control", "no cache")

Willy:

动态网站会起作用吗?

静态页面由 Go 按原样渲染。 包含动态数据的静态页面,其数据被传递给模板以 {{.}} 的形式呈现,并由 Go 渲染。 完全动态的页面通常由 JavaScript 构建并由浏览器渲染。

还有一些页面由 Go 渲染,其部分内容使用 JavaScript 和 innerHTML 进行更新。

这就是我的理解。但“动态”这个术语的含义是模糊的。

Willy:

我的网站中有一些文件(.css、.js、.html)会经常变动,但同时还有许多其他文件(具有上述相同的扩展名)将始终保持静态,因此我想告诉浏览器允许缓存哪些文件。我该如何使用 Go 来实现?

另一方面,我读到浏览器总是会缓存 .html 文件,如果这是真的,那么动态网站该如何工作呢?那将迫使大量使用 JavaScript,并且不允许使用模板等技术。值得一提的是,我是在旧帖子中读到这些信息的,找不到最新的信息,但我的直觉告诉我,目前任何浏览器都会缓存 .html 文件,对吗?

对于动态 HTML 内容,你通常需要根据用户请求或业务逻辑来生成或渲染 HTML 内容。在下面的示例中,一个简单的动态 HTML 内容直接在请求处理函数中生成。

func main() {
    fmt.Println("hello world")
}

不要在客户端做任何操作。服务器端会指示缓存控制。浏览器会根据它获取的每个资源的缓存控制头部知道该做什么。

这里是您可以在客户端做的事情,但我会避免这样做,只在服务器端设置适当的头部。

以下是更多与缓存相关的链接:

在Go中控制浏览器缓存主要通过设置HTTP响应头实现。对于经常变动的文件,应设置Cache-Control: no-cacheCache-Control: no-store;对于静态文件,可设置较长的缓存时间并配合版本控制。

以下是具体实现示例:

package main

import (
    "net/http"
    "path/filepath"
    "strings"
)

func main() {
    fs := http.FileServer(http.Dir("./static"))
    
    http.Handle("/static/", http.StripPrefix("/static/", 
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // 设置缓存策略
            ext := strings.ToLower(filepath.Ext(r.URL.Path))
            
            switch ext {
            case ".css", ".js":
                // 静态资源设置长期缓存(1年)
                w.Header().Set("Cache-Control", "public, max-age=31536000")
                // 添加版本号或哈希到文件名(如style.v123.css)
                // 实际项目中可通过构建工具自动生成
            case ".html":
                // HTML文件不缓存或短时间缓存
                w.Header().Set("Cache-Control", "no-cache")
                // 或者使用以下策略:
                // w.Header().Set("Cache-Control", "max-age=0, must-revalidate")
            default:
                // 其他文件默认缓存策略
                w.Header().Set("Cache-Control", "public, max-age=3600")
            }
            
            fs.ServeHTTP(w, r)
        }),
    ))
    
    http.ListenAndServe(":8080", nil)
}

对于动态内容,现代浏览器确实会缓存HTML,但正确的缓存头设置可以控制这一行为:

// 动态HTML响应示例
func dynamicHandler(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")
    
    // 生成动态内容
    data := struct {
        Title string
        Time  string
    }{
        Title: "动态页面",
        Time:  time.Now().Format("2006-01-02 15:04:05"),
    }
    
    // 使用模板渲染
    tmpl, _ := template.ParseFiles("template.html")
    tmpl.Execute(w, data)
}

对于版本控制,推荐使用内容哈希:

// 通过ETag实现缓存验证
func staticHandler(w http.ResponseWriter, r *http.Request) {
    content := []byte("/* CSS内容 */")
    hash := fmt.Sprintf("%x", md5.Sum(content))
    
    w.Header().Set("ETag", `"`+hash+`"`)
    
    // 如果客户端有缓存且未过期,返回304
    if match := r.Header.Get("If-None-Match"); match == `"`+hash+`"` {
        w.WriteHeader(http.StatusNotModified)
        return
    }
    
    w.Header().Set("Cache-Control", "public, max-age=31536000")
    w.Write(content)
}

关于浏览器缓存HTML的问题:现代浏览器会缓存HTML,但开发者可以通过以下方式控制:

  1. 服务器端控制:如上所示,通过Cache-Control头部
  2. URL版本化/page.html?v=2/page-2.html
  3. HTML5应用缓存已废弃,建议使用Service Workers

动态网站通过以下技术避免缓存问题:

  • 服务器端渲染时设置正确的缓存头
  • 单页应用(SPA)使用JavaScript动态加载内容
  • API响应设置Cache-Control: no-cache
  • 使用WebSocket或Server-Sent Events实时更新

实际项目中,建议结合构建工具自动添加文件哈希:

// 示例:在构建时生成带哈希的文件名
// style.abc123.css -> 设置长期缓存
// index.html -> 设置no-cache

这样既能充分利用浏览器缓存提高性能,又能确保用户获取到最新内容。

回到顶部