Firebase 托管:如何防止对 SPA 的 index.html 进行缓存

Posted

技术标签:

【中文标题】Firebase 托管:如何防止对 SPA 的 index.html 进行缓存【英文标题】:Firebase hosting: How to prevent caching for the index.html of an SPA 【发布时间】:2018-07-13 09:01:35 【问题描述】:

我在 firebase 上托管一个 SPA,其中几乎所有路径都被重写为 index.html。我正在使用基于 webpack 哈希的缓存破坏,所以我想始终阻止缓存我的 index.html,但不阻止任何其他文件。我发现这样做非常困难。具体来说,我的文件布局是这样的

/
├── index.html
├── login.html
├── js
│   ├── login.ba22ef2579d744b26c65.bundle.js
│   └── main.6d0ef60e45ae7a11063c.bundle.js
└── public
    └── favicon-16x16.ico

在阅读文档中的这句话之前,我天真地开始使用 "sources": "index.html"

无论使用glob notation 的任何重写规则如何,每个定义都必须有一个与原始请求路径匹配的源键。

好的,所以不是一个简单的 glob 来指定我想要这些标题的文件,我想我需要一个路径。由于大多数路径都重定向到 index.html,因此我需要一个排除所有我不想放置这些标头的路径的 glob。

作为参考,我的firebase.json 托管部分如下所示:


  "hosting": 
    "public": "dist",
    "rewrites": [
      
        "source": "**",
        "destination": "/index.html"
      
    ],
    "cleanUrls": true,
    "trailingSlash": false,
    "headers": [
      
        "source": <<<WHAT-GOES-HERE?>>>,
        "headers": [
          
            "key": "Cache-Control",
            "value": "no-cache, no-store, must-revalidate"
          ,
          
            "key": "Pragma",
            "value": "no-cache"
          ,
          
            "key": "Expires",
            "value": "0"
          
        ]
      
    ]
  

所以,举一些重定向到 index.html 并且不应该被缓存的例子

mysite.com  
mysite.com/  
mysite.com/foo/bar/baz  
mysite.com/index.html 

注意:如果最后一个被缓存,我可以活下去,因为它在实践中没有得到使用。

以及不重定向到 index.html 且不应该缓存的东西

**/*.* (ideally excluding index.html)
mysite.com/login  

我自己得到的最接近的是**/!(login|*.*),它几乎适用于上面列出的所有内容,但莫名其妙地不适用于mysite.commysite.com/。这两页没有被这个 glob 匹配,我不知道为什么。

【问题讨论】:

您是否尝试过为/index.html额外添加规则? 添加带有简单“/”源全局的第二部分似乎对我有用。我将不回答这个问题,因为如果这可以在单个 glob/section 中完成会更加优雅。 【参考方案1】:

这是我正在使用的配置。逻辑是对所有静态文件(如images, css, js 等)使用缓存。对于所有其他文件,即"source": "/**" 将缓存设置为无缓存。因此对于所有其他文件,可能不会应用 example.com、example.com/index.html、example.com/about-us、example.com/about-us.html 缓存。


  "hosting": 
    "public": "dist",
    "headers": [
      
        "source": "/**",
        "headers": [
          
            "key": "Cache-Control",
            "value": "no-cache, no-store, must-revalidate"
          
        ]
      ,
      
        "source":
          "**/*.@(jpg|jpeg|gif|png|svg|webp|js|css|eot|otf|ttf|ttc|woff|woff2|font.css)",
        "headers": [
          
            "key": "Cache-Control",
            "value": "max-age=604800"
          
        ]
      
    ],
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
  

【讨论】:

添加 webp 到我的 :) @GijoVargehese 虽然我们在这里,但 wasm 可能也有意义 如何确保service-worker.js 也不会被缓存? 我发现使用这种方法它会增加 300-400 毫秒到 CDN 的 index.html 页面加载时间(就像 CDN 本身完全停止缓存它一样),即使将硬刷新与硬刷新进行比较也是如此。有什么办法可以两全其美,在文件更改时使缓存失效,始终让客户端从 CDN 获取最新的? 更新:回答我自己的问题(很想知道这是个好主意还是坏主意)- 使用 Cache-Control 值:max-age=0, s-maxage=604800 似乎得到了我想要的即时客户端更新行为在新页面内容上,但仍缓存在 CDN 级别

以上是关于Firebase 托管:如何防止对 SPA 的 index.html 进行缓存的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React 和 Firebase 托管在 SPA 上提供 robots.txt?

如何在 firebase 托管的 webapp 中获取 firebase 函数 URL?

SPA - Firebase 和 .Net WebApi 2 身份验证

在 Firebase 托管中使用 vue-router 部署 Quasar (VueJS)

Firebase托管丢失的文件夹

如何使用 Firebase 托管来托管图像?