You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7+Heroku+Fastly环境下如何禁止缓存PWA的sw.js文件?

Rails 7 + Heroku + Fastly 环境下Service Worker(sw.js)无缓存部署最佳实践

核心需求

要确保sw.js文件直接从Heroku后端获取,不被Fastly CDN缓存,同时浏览器也不会缓存该文件,保证Service Worker能实时更新。

方案一:修改Fastly VCL规则(绕过CDN缓存)

针对你提供的默认vcl_recv子程序,添加判断逻辑,当请求路径为/sw.js时,直接跳过CDN缓存,回源到Heroku后端。

修改后的vcl_recv代码:

#--FASTLY RECV BEGIN
  if (req.restarts == 0) {
    if (!req.http.X-Timer) {
      set req.http.X-Timer = "S" time.start.sec "." time.start.usec_frac;
    }
    set req.http.X-Timer = req.http.X-Timer ",VS0";
  }
    set req.http.Fastly-Orig-Host = req.http.host;
    set req.http.host = "my-app.herokuapp.com";
  declare local var.fastly_req_do_shield BOOL;
  set var.fastly_req_do_shield = (req.restarts == 0);
  # default conditions
  set req.backend = F_kinscape_production_herokuapp_com__Heroku_;
    # end default conditions
#--FASTLY RECV END
    # 新增:针对sw.js跳过CDN缓存,直接回源
    if (req.url == "/sw.js") {
      return(pass);
    }
    if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
      return(pass);
    }
    return(lookup);
}

代码说明

新增的if (req.url == "/sw.js") { return(pass); }会让Fastly直接将请求转发到Heroku后端,不经过CDN缓存层,确保每次请求都获取最新的sw.js。

方案二:设置浏览器端无缓存头

即使CDN回源,仍需确保浏览器不会缓存sw.js,可通过两种方式实现:

方式1:在Fastly的vcl_deliver子程序中添加缓存控制头

在Fastly的VCL配置中添加vcl_deliver规则,对sw.js返回强缓存禁止的响应头:

if (req.url == "/sw.js") {
    set resp.http.Cache-Control = "no-cache, no-store, must-revalidate";
    set resp.http.Pragma = "no-cache";
    set resp.http.Expires = "0";
  }
}

方式2:通过Rails配置设置静态文件头

在Rails项目的config/initializers/assets.rb中添加配置,让sw.js返回正确的缓存头:

Rails.application.config.public_file_server.headers = {
  "Cache-Control" => "no-cache, no-store, must-revalidate",
  "Pragma" => "no-cache",
  "Expires" => "0"
}

如果只想针对sw.js单独配置,也可以将sw.js移到app/assets/javascripts,通过控制器返回并设置响应头,但静态文件直接配置更简洁。

补充:默认vcl_recv子程序中文翻译与说明

#--FASTLY RECV 开始
  # 如果是首次请求(未重启)
  if (req.restarts == 0) {
    # 初始化X-Timer头,记录请求开始时间
    if (!req.http.X-Timer) {
      set req.http.X-Timer = "S" time.start.sec "." time.start.usec_frac;
    }
    # 添加VS0标记到X-Timer头
    set req.http.X-Timer = req.http.X-Timer ",VS0";
  }
    # 保存原始请求的Host头
    set req.http.Fastly-Orig-Host = req.http.host;
    # 将请求Host设置为Heroku应用的域名
    set req.http.host = "my-app.herokuapp.com";
  # 声明本地变量,标记是否需要使用屏蔽层(Shield)
  declare local var.fastly_req_do_shield BOOL;
  # 仅首次请求时使用屏蔽层
  set var.fastly_req_do_shield = (req.restarts == 0);
  # 默认后端配置
  set req.backend = F_kinscape_production_herokuapp_com__Heroku_;
    # 结束默认条件
#--FASTLY RECV 结束
    # 非HEAD/GET/FASTLYPURGE请求直接回源
    if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
      return(pass);
    }
    # 其他请求进入CDN缓存查找流程
    return(lookup);
}

内容的提问来源于stack exchange,提问作者Meltemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:47:37