【问题标题】:How to circumvent a browser cache when Cache-Control header is not allowed in Access-Control-Allow-Headers当 Access-Control-Allow-Headers 中不允许 Cache-Control 标头时如何规避浏览器缓存
【发布时间】:2019-12-03 01:56:52
【问题描述】:

我正在使用 GitHub API 来请求需要更新的通知。问题是我的浏览器经常从浏览器缓存而不是从 Internet 加载我的请求的答案,这当然不是最新的。 为了防止这种情况并告诉浏览器不要使用缓存,我读到应该使用Cache-Control 标头。 问题是 GitHub API 在其 Access-Control-Allow-Headers 中似乎没有 Cache-Control 标头,因此我不允许在我的请求中使用 Cache-Control 标头。

那么,如果我不允许使用 Cache-Control 标头,我应该如何防止我的浏览器从缓存中加载响应?为什么 GitHub API 首先禁止 Cache-Control 标头,有什么好的理由吗?

只是为了提供更多上下文,我在 JavaScript 中使用 fetch API 并尝试了下面的代码

res = await fetch('https://api.github.com/notifications', {method: 'Get', 
    headers: {    
        'accept': 'application/vnd.github.v3+json', 
        'authorization': "token " + token,  
        'Cache-Control': 'no-cache'               
}});

我收到错误消息:

从原点获取 'https://api.github.com/notifications' 的访问权限 'http://127.0.0.1:5500' 已被 CORS 策略阻止:请求 头字段缓存控制不允许 预检响应中的 Access-Control-Allow-Headers。

您能推荐我解决我的问题的最佳解决方案吗?

【问题讨论】:

  • 您可以尝试使用查询参数破坏缓存吗? https://api.github.com/notifications?cachebust=123456?

标签: javascript http cors github-api fetch-api


【解决方案1】:

来自 GitHub 文档上的 notifications page...

通知已针对使用 Last-Modified 标头进行轮询进行了优化。如果没有新通知,您将看到 304 Not Modified 响应,保持当前速率限制不变。有一个 X-Poll-Interval 标头指定允许轮询的频率(以秒为单位)。在服务器负载高的时候,时间可能会增加。请遵守标题。

他们还使用 curl 提供了这个示例...

# Add authentication to your requests
curl -I https://api.github.com/notifications
HTTP/1.1 200 OK
Last-Modified: Thu, 25 Oct 2012 15:16:27 GMT
X-Poll-Interval: 60

# Pass the Last-Modified header exactly
curl -I https://api.github.com/notifications
   -H "If-Modified-Since: Thu, 25 Oct 2012 15:16:27 GMT"
HTTP/1.1 304 Not Modified
X-Poll-Interval: 60

他们使用Last-Modified 标头,其中包含上次更新通知的日期。您在请求中使用 If-Modified-Since 标头将该日期回显到服务器,如果内容没有更改,您将收到不包含任何内容的“304 Not Modified”状态响应。

正如正文所说,它们还提供了一个轮询间隔标题,您应该阅读并确保通知更新功能不会比指定的间隔更频繁地运行,在他们的示例中是“60”(秒)的意思“每分钟不超过一次”。

关于另一个答案的注释 - 您绝对不应该使用缓存破坏查询参数。 GitHub 提供了一种机制来控制缓存并控制其服务器上的负载以保持可用性。忽视这一点会给每个人带来问题,并且可能违反他们的使用条款。

【讨论】:

  • 谢谢,以后想在 X-Poll-Interval 中构建。在开发的这个阶段,我想保持简单,直到我了解基本的东西。说了这么多,一分钟后就不能再使用cache bust查询参数来保证缓存被忽略了吗?
  • 如果你使用它,你将使一个完美的缓存版本失效。如果事情实际发生了变化,您只需要下载通知和更新内容,这就是 If-Modified-Since 给您的。 Cache bust 每次都会盲目下载通知。
【解决方案2】:

所以我通过在请求中使用查询参数解决了这个问题,感谢 zero298 注释

let cachebust = window.localStorage.getItem("cachebust253");
if(cachebust === null) {cachebust = 0;}
res = await fetch('https://api.github.com/notifications?cache_bust=${cachebust}', {method: 'Get', 
    headers: {    
        'accept': 'application/vnd.github.v3+json', 
        'authorization': "token " + token,                
}});
window.localStorage.setItem("cachebust253", parseInt(cachebust)+1);

编辑:虽然这不是有效的解决方案,但对于 github,它不尊重 github api 政策。正如 dezfowler 所指出的,必须尊重 github api 的 x-poll-interval 标头

【讨论】:

  • 请看我的回答。 GitHub API 中提供了正确的方法。
猜你喜欢
  • 2015-06-17
  • 2016-11-24
  • 2016-05-15
  • 1970-01-01
  • 2016-08-24
  • 2016-04-24
  • 2019-02-21
  • 1970-01-01
  • 2015-06-03
相关资源
最近更新 更多