Golang中HTML响应的"no-store"指令是否适用于.css、.js和图片文件?

Golang中HTML响应的"no-store"指令是否适用于.css、.js和图片文件? 假设客户端想要访问这个网址:somepage.com

我使用 somepage.html 文件的内容进行响应:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
	<img src="dinosaur.jpg" />
	<script src="index.js"></script>
  </body>
</html>

并且在响应头中设置了以下指令:

w.Header().Set("Cache-Control", "no-store;must-revalidate")

我的问题是,这三个文件(style.cssindex.jsdinosaur.jpg)会被缓存吗?

no-store 指令是仅影响 somepage.html 文件,还是也会影响该 .html 文件中的所有文件?


更多关于Golang中HTML响应的"no-store"指令是否适用于.css、.js和图片文件?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我相当确定你需要为每个HTTP响应设置头部,但浏览器有时很奇怪,并不总是遵循规范,所以如果你有更多信息,请随时补充。根据MDN

区分不同响应的方式基本上是基于它们的URL:

URL 响应体
https://example.com/index.html <!doctype html>...
https://example.com/style.css body { ...
https://example.com/script.js function main () { ...

所以,它显然期望你的每个请求都设置自己的缓存控制头部。如果你阅读RFC9111:

IETF Datatracker

RFC 9111: HTTP Caching

超文本传输协议(HTTP)是一种用于分布式、协作式、超文本信息系统的无状态应用级协议。本文档定义了HTTP缓存以及控制缓存行为或指示…的相关头部字段。

其中没有提到对索引页面头部级联到子元素的特殊处理。你的HTML页面加载的资源可能来自完全不同的服务器,例如 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">,而那个CDN会希望能够在它们那一侧控制缓存头部。HTTP在很大程度上并不关心它传输的内容类型(尽管浏览器显然关心!)。

总结:在你希望控制缓存的所有HTTP响应中都添加头部。

更多关于Golang中HTML响应的"no-store"指令是否适用于.css、.js和图片文件?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


no-store 指令仅作用于设置该响应头的特定资源,不会自动传播到其他资源。在您的示例中,只有 somepage.html 文件会应用 no-store 指令,而 style.cssindex.jsdinosaur.jpg 这三个文件是否被缓存取决于它们各自的响应头设置。

每个资源(HTML、CSS、JS、图片)的缓存行为由其自身的 HTTP 响应头中的 Cache-Control 指令独立控制。浏览器会分别处理每个资源的缓存。

示例代码:

如果您希望所有资源都不被缓存,需要为每个资源单独设置响应头:

// 处理HTML文件
func serveHTML(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-store, must-revalidate")
    http.ServeFile(w, r, "somepage.html")
}

// 处理CSS文件  
func serveCSS(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-store, must-revalidate")
    http.ServeFile(w, r, "style.css")
}

// 处理JS文件
func serveJS(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-store, must-revalidate")
    http.ServeFile(w, r, "index.js")
}

// 处理图片文件
func serveImage(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-store, must-revalidate")
    http.ServeFile(w, r, "dinosaur.jpg")
}

func main() {
    http.HandleFunc("/", serveHTML)
    http.HandleFunc("/style.css", serveCSS)
    http.HandleFunc("/index.js", serveJS)
    http.HandleFunc("/dinosaur.jpg", serveImage)
    http.ListenAndServe(":8080", nil)
}

或者使用中间件统一设置:

func noCacheMiddleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Cache-Control", "no-store, must-revalidate")
        next.ServeHTTP(w, r)
    }
}

func main() {
    http.HandleFunc("/", noCacheMiddleware(func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "somepage.html")
    }))
    
    http.HandleFunc("/style.css", noCacheMiddleware(func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "style.css")
    }))
    
    // 其他资源类似处理...
    http.ListenAndServe(":8080", nil)
}

关键点:

  1. no-store 指令不会级联或继承到子资源
  2. 每个资源的缓存策略必须单独指定
  3. 浏览器对每个资源的请求都会检查其自身的响应头
  4. 如果子资源没有设置 no-store,浏览器可能会根据默认策略或启发式算法缓存它们
回到顶部