为何Safari及iOS端浏览器无法缓存我的SVG资源?
我搭建了一套Flask后端+Nginx反向代理的服务,计划后续用Nginx接管静态资源,但当前需要先实现Flask提供资源时的缓存功能。目前在Windows、Linux、macOS的Chrome、Chromium、Firefox中都能正常缓存SVG等静态资源,但macOS Safari及所有iOS浏览器完全无法缓存SVG资源。
我试过多种Header组合都无效:
- 对比缓存正常的网站复刻其Header配置
- 添加Expires头(尽管Cache-Control指定时非必需)
- 给Cache-Control添加
immutable标识 - 完全移除ETag
- 开启/关闭SVG压缩,结果无差异
Flask压缩配置代码
app_instance = Flask(__name__, static_folder="static", static_url_path="") Compress(app_instance) app_instance.config["COMPRESS_MIMETYPES"].append("image/svg+xml")
缓存Header修改代码
@app.after_request def after_request(response): ext = request.path.split(".")[-1] if ext in ["png", "svg", "ttf", "jpg"]: response.cache_control.public = True response.cache_control.max_age = 60 response.cache_control.no_cache = None if ext == "svg": # 之前是 "image/svg+xml; charset=utf-8" response.content_type = "image/svg+xml" response.headers["Strict-Transport-Security"] = "max-age=63072000" return response
请求响应示例
macOS Safari首次请求(后续无法缓存)
请求头
GET /images/products/59.svg HTTP/1.1
Accept: image/webp,image/avif,image/jxl,image/heic,image/heic-sequence,video/;q=0.8,image/png,image/svg+xml,image/;q=0.8,/;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Host: www..com
Referer: https://www..com/
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.1.1 Safari/605.1.15
响应头
HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Connection: keep-alive
Content-Disposition: inline; filename=59.svg
Content-Encoding: br
Content-Length: 3606
Content-Type: image/svg+xml
Date: Tue, 31 Dec 2024 14:28:22 GMT
ETag: "1735522441.7048287-18829-3530625642:br"
Last-Modified: Mon, 30 Dec 2024 01:34:01 GMT
Server: nginx/1.22.1
Strict-Transport-Security: max-age=63072000
Vary: Accept-Encoding
Windows Chrome首次请求(后续可正常缓存)
请求头
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/,/*;q=0.8
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,lt-LT;q=0.8,lt;q=0.7,ja-JP;q=0.6,ja;q=0.5
Connection: keep-alive
Host: www..com
Pragma: no-cache
Referer: https://www..com/
Sec-Ch-Ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
响应头
HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Connection: keep-alive
Content-Disposition: inline; filename=59.svg
Content-Encoding: br
Content-Length: 3606
Content-Type: image/svg+xml
Date: Wed, 01 Jan 2025 16:14:08 GMT
ETag: "1735522441.7048287-18829-3530625642:br"
Last-Modified: Mon, 30 Dec 2024 01:34:01 GMT
Server: nginx/1.22.1
Strict-Transport-Security: max-age=63072000
Vary: Accept-Encoding
Curl请求结果
执行命令 curl -I https://www.<my-domain>.com/images/products/59.svg 返回:
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Wed, 01 Jan 2025 16:26:15 GMT
Content-Type: image/svg+xml
Content-Length: 18829
Connection: keep-alive
Content-Disposition: inline; filename=59.svg
Last-Modified: Mon, 30 Dec 2024 01:34:01 GMT
Cache-Control: public, max-age=60
ETag: "1735522441.7048287-18829-3530625642"
Strict-Transport-Security: max-age=63072000
Vary: Accept-Encoding
补充说明
- 已将Nginx配置为使用HTTP/2,问题依旧
- 移除压缩后(ETag不再附加后缀),Safari仍无法识别SVG未更新,不会返回304,而是重新请求所有SVG资源
内容的提问来源于stack exchange,提问作者star8163264

