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"))
|
|
|
|
|
|
}
|