Files

66 lines
2.1 KiB
Go
Raw Permalink Normal View History

2024-01-02 14:45:34 +08:00
package middleware
import (
"github.com/gin-gonic/gin"
"strings"
2026-01-15 20:47:42 +08:00
"time"
2024-01-02 14:45:34 +08:00
)
// StaticCacheMiddleware add embed file static cache
func StaticCacheMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
2026-01-15 20:47:42 +08:00
path := c.Request.URL.Path
// 对静态资源应用缓存策略
if strings.HasPrefix(path, "/assets/") || strings.Contains(path, "/assets/") {
// 检查文件类型
if isVersionedAsset(path) {
// 带版本号的资源(如 index-Bw4BKttg.js)可以长期缓存
// 使用 immutable 指令,浏览器在缓存期内不会重新验证
c.Header("Cache-Control", "public, max-age=31536000, immutable")
} else {
// 其他静态资源使用较短的缓存时间
c.Header("Cache-Control", "public, max-age=86400")
}
// 添加 ETag 支持
c.Header("ETag", `"`+path+`"`)
// 添加 Expires 头(兼容旧浏览器)
expires := time.Now().Add(24 * time.Hour).UTC().Format(time.RFC1123)
c.Header("Expires", expires)
// 添加 Vary 头,告诉缓存服务器根据这些头部区分缓存
c.Header("Vary", "Accept-Encoding")
} else if path == "/" || strings.HasSuffix(path, ".html") {
// HTML 文件不缓存或使用协商缓存
c.Header("Cache-Control", "no-cache, must-revalidate")
c.Header("Pragma", "no-cache")
c.Header("Expires", "0")
2024-01-02 14:45:34 +08:00
}
2026-01-15 20:47:42 +08:00
2024-01-02 14:45:34 +08:00
// Continue to the next middleware or handler
c.Next()
}
}
2026-01-15 20:47:42 +08:00
// isVersionedAsset 检查是否是带版本号的资源文件
// Vite 构建的文件通常包含 hash,如:index-Bw4BKttg.js
func isVersionedAsset(path string) bool {
// 检查是否包含 hash 模式(通常是 -[hash].js 或 -[hash].css
return strings.Contains(path, "-") &&
(strings.HasSuffix(path, ".js") ||
strings.HasSuffix(path, ".css") ||
strings.HasSuffix(path, ".woff") ||
strings.HasSuffix(path, ".woff2") ||
strings.HasSuffix(path, ".ttf") ||
strings.HasSuffix(path, ".eot") ||
strings.HasSuffix(path, ".svg") ||
strings.HasSuffix(path, ".png") ||
strings.HasSuffix(path, ".jpg") ||
strings.HasSuffix(path, ".jpeg") ||
strings.HasSuffix(path, ".gif") ||
strings.HasSuffix(path, ".webp") ||
strings.HasSuffix(path, ".ico"))
}