Files
2026-01-15 20:47:42 +08:00

66 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package middleware
import (
"github.com/gin-gonic/gin"
"strings"
"time"
)
// StaticCacheMiddleware add embed file static cache
func StaticCacheMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
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")
}
// Continue to the next middleware or handler
c.Next()
}
}
// 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"))
}