Golang中如何添加Expires头部

Golang中如何添加Expires头部 我在使用Go为网站添加缓存时遇到了困难。主要有两种解决方案:添加到robots.txt或添加到<head>中。

<IfModule mod_expires.c>
  ExpiresActive on

# Your document html
  ExpiresByType text/html "access plus 0 seconds"

# Media: images, video, audio
  ExpiresByType image/jpeg "access plus 1 week"
  ExpiresByType image/png "access plus 1 week"
  ExpiresByType video/mp4 "access plus 1 week"

# CSS and JavaScript
  ExpiresByType application/javascript "access plus 1 week"
  ExpiresByType text/css "access plus 1 week"
</IfModule>

我理解这是在您使用Apache时的配置吗?

或者,我尝试在头部添加这个:

  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, minimum-scale=1 user-scalable=no">
    <link rel="stylesheet" type="text/css" href="css/layout.css">
    <script src="/js/accordion.js" defer></script> 
    Cache-Control: public, max-age=86400
  </head>

以下是我用于“端点”和robots.txt的简化代码。Google可以读取robots.txt。

func index(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	path := strings.Trim(r.URL.Path, "/")

	switch path {
	case "robots.txt":
		http.ServeFile(w, r, "public/static/robots.txt")
	default:
		path = (path + ".html")
	}

}

在使用Go时,我该如何控制缓存?


更多关于Golang中如何添加Expires头部的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

我不太确定是否完全理解了你的问题。不过,Go 语言编写的 Web 应用程序并不需要外部的 Web 服务器(如 Apache、Nginx 等)。另一方面,在服务器端管理缓存意味着需要向响应写入器添加适当的头部信息,例如:

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

更多关于Golang中如何添加Expires头部的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


geosoft1:

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

目标是缓存网站几天以提升速度。

在HTML头部实现此功能的语法是什么?我猜在模板中也可以做到?

meta-tag-refresh.gif

5 Things You Can Do With HTML Meta Tag - Hongkiat

元标签用于在网页上存储信息。本质上,它是关于数据的信息。其目的是供浏览器和搜索引擎使用。

浏览器首先检查响应头以进行缓存,如果响应头不包含缓存头,则检查HTML标签。如果HTML不包含缓存标签,浏览器将使用默认的缓存行为。从Go端来看,正如@geosoft1回复的那样,对于许多浏览器来说已经足够了。

w.Header().Set(“Cache-Control”, “no-store, no-cache”)

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

Meta Tag 用于在网页上存储一条信息。

我有点困惑。似乎存在两个不同的头部,而且 HTML5 不在 html 头部中使用缓存。有人能确认这一点吗?

BalusC

如何控制所有浏览器中的网页缓存?

标签: http, caching, https, http-headers

BalusC 回答

在Go中控制缓存主要通过设置HTTP响应头实现,而不是在HTML或robots.txt中添加。以下是几种设置Expires和缓存控制头的方法:

1. 设置Expires头部(传统方式)

func handler(w http.ResponseWriter, r *http.Request) {
    // 设置Expires头部(HTTP/1.0)
    expiresTime := time.Now().Add(24 * time.Hour)
    w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
    
    // 同时设置Cache-Control(HTTP/1.1)
    w.Header().Set("Cache-Control", "public, max-age=86400")
    
    // 写入响应内容
    w.Write([]byte("响应内容"))
}

2. 针对不同文件类型设置缓存

func staticFileHandler(w http.ResponseWriter, r *http.Request) {
    filePath := r.URL.Path[1:] // 去掉前导斜杠
    
    // 根据文件扩展名设置不同的缓存时间
    switch {
    case strings.HasSuffix(filePath, ".html"):
        w.Header().Set("Cache-Control", "no-cache, must-revalidate")
        w.Header().Set("Expires", "0")
        
    case strings.HasSuffix(filePath, ".css"), strings.HasSuffix(filePath, ".js"):
        w.Header().Set("Cache-Control", "public, max-age=604800") // 1周
        expiresTime := time.Now().Add(7 * 24 * time.Hour)
        w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
        
    case strings.HasSuffix(filePath, ".jpg"), strings.HasSuffix(filePath, ".png"),
         strings.HasSuffix(filePath, ".gif"):
        w.Header().Set("Cache-Control", "public, max-age=2592000") // 30天
        expiresTime := time.Now().Add(30 * 24 * time.Hour)
        w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
        
    default:
        w.Header().Set("Cache-Control", "public, max-age=3600") // 默认1小时
    }
    
    http.ServeFile(w, r, filePath)
}

3. 使用中间件统一处理缓存头

func cacheMiddleware(next http.HandlerFunc, cacheDuration time.Duration) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 设置缓存头
        w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", int(cacheDuration.Seconds())))
        
        // 设置Expires头部
        expiresTime := time.Now().Add(cacheDuration)
        w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
        
        // 调用下一个处理器
        next(w, r)
    }
}

// 使用示例
func main() {
    // 静态文件处理,缓存1周
    http.HandleFunc("/static/", cacheMiddleware(staticHandler, 7*24*time.Hour))
    
    // HTML页面,不缓存
    http.HandleFunc("/", cacheMiddleware(indexHandler, 0))
    
    http.ListenAndServe(":8080", nil)
}

4. 完整的示例:处理静态文件并设置缓存

func serveStaticWithCache(w http.ResponseWriter, r *http.Request) {
    filePath := "public" + r.URL.Path
    
    // 检查文件是否存在
    if _, err := os.Stat(filePath); os.IsNotExist(err) {
        http.NotFound(w, r)
        return
    }
    
    // 获取文件信息
    info, err := os.Stat(filePath)
    if err != nil {
        http.Error(w, "Internal Server Error", http.StatusInternalServerError)
        return
    }
    
    // 设置Last-Modified头部
    w.Header().Set("Last-Modified", info.ModTime().UTC().Format(http.TimeFormat))
    
    // 根据文件类型设置缓存策略
    contentType := mime.TypeByExtension(filepath.Ext(filePath))
    w.Header().Set("Content-Type", contentType)
    
    switch {
    case strings.Contains(contentType, "text/html"):
        // HTML文件不缓存
        w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
        w.Header().Set("Pragma", "no-cache")
        w.Header().Set("Expires", "0")
        
    case strings.Contains(contentType, "text/css"), 
         strings.Contains(contentType, "application/javascript"):
        // CSS和JS缓存1周
        w.Header().Set("Cache-Control", "public, max-age=604800")
        expiresTime := time.Now().Add(7 * 24 * time.Hour)
        w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
        
    case strings.Contains(contentType, "image/"):
        // 图片缓存1个月
        w.Header().Set("Cache-Control", "public, max-age=2592000")
        expiresTime := time.Now().Add(30 * 24 * time.Hour)
        w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
        
    default:
        // 其他文件缓存1小时
        w.Header().Set("Cache-Control", "public, max-age=3600")
    }
    
    // 提供文件
    http.ServeFile(w, r, filePath)
}

func main() {
    http.HandleFunc("/", serveStaticWithCache)
    http.ListenAndServe(":8080", nil)
}

5. 针对robots.txt的特殊处理

func robotsHandler(w http.ResponseWriter, r *http.Request) {
    // robots.txt通常不缓存或短期缓存
    w.Header().Set("Content-Type", "text/plain")
    w.Header().Set("Cache-Control", "public, max-age=3600") // 缓存1小时
    expiresTime := time.Now().Add(1 * time.Hour)
    w.Header().Set("Expires", expiresTime.UTC().Format(http.TimeFormat))
    
    // 提供robots.txt内容
    http.ServeFile(w, r, "public/static/robots.txt")
}

关键点:

  1. Cache-Control是HTTP/1.1的标准,优先级高于Expires
  2. max-age以秒为单位
  3. 对于动态内容(如HTML),通常设置为no-cache或较短的缓存时间
  4. 静态资源(CSS、JS、图片)可以设置较长的缓存时间
  5. 使用Last-Modified头部可以帮助浏览器进行条件请求
回到顶部