首页 > 解决方案 > 许多 HTTP 304 响应导致更少的 GET 请求

问题描述

我有一个 Django 开发服务器托管一个网页,该网页实时(ish)显示从我监视的众多服务器收集的信息。这个网页仍在开发中,所以我目前正在使用 Django 提供的内置网络主机,在 Ubuntu 主机上启动:

python3 manage.py runserver IP:Port

在同一个 ubuntu 主机上,有一个 python 脚本不断地连接到受监控的服务器,并将响应格式化为一个 .html 文件,客户端在<div>每分钟内重新加载该文件。客户端访问的页面的一般功能如下:

<div id="status" style="width:100%; height: 1000"></div>
<script>
    $('#status').load("{% static 'alerts/status.html' %}");
    setInterval(function() {
        $('#status').load("{% static 'alerts/status.html' %}");
    }, 60000);
</script>

...因此页面在页面加载时加载status.html分区内的文件,然后每分钟重新加载一次。这一直很好,但是,我注意到查看 Django 日志,如果在十个状态 304(未修改)响应之后 status.html 没有更改,则请求之间的等待时间开始减少。也就是说,不是等待 1 分钟,而是等待 2 分钟,然后是 5 分钟,依此类推(大致,我忘记了实际的滚降率)。

现在我面临的问题是我的服务器在周末出现故障(无关),但是我打开网页的显示屏仍然处于活动状态,所以它滚落得如此之多,以至于它似乎完全坏了,拒绝下载最新的 status.html,即使我强制 Chrome 重新加载所有内容并且不使用缓存(ctrl + Rshift + F5)。

我尝试研究此滚降,但找不到任何信息。我认为这是谷歌浏览器(我正在使用的浏览器)内置的东西,以在页面没有变化时节省带宽,但我的状态页面最多只有几千字节,并且 304 响应已经节省了一点带宽,如果有一种方法可以完全禁用这种用于生产的滚降,这将是理想的。

无论如何,任何关于我为什么看到这种行为/它来自哪里的信息都将不胜感激,因为我似乎找不到任何关于它的文档。我发现的最接近的内容来自 Google 的关于缓存的开发人员文档它提到了定义最大年龄和无缓存行为的能力,所以我可以强制客户端每分钟重新下载 status.html ,但这似乎很混乱。虽然这在我的特定场景中可以工作,因为 status.html 最多只有几千字节,但只要禁用这种滚降行为就可以解决问题,并且会降低不必要的带宽。

标签: djangogoogle-chromedjango-staticfileshttp-caching

解决方案


这里的问题是响应status.html没有明确的缓存过期标头。在没有这样的标头的情况下,浏览器可以自由地使用自己的算法(例如您看到的滚降)来选择过期时间。来自RFC 7234

由于原始服务器并不总是提供明确的过期时间,缓存可以在未指定明确时间时分配启发式过期时间......本规范不提供特定算法。

所以解决方案很简单:分配一个显式的缓存过期时间。

不幸的是,使用 Django 的 staticfiles 应用程序实现此解决方案并非易事。这个应用程序更好的默认设置是根本不缓存结果,但该解决方案在与whitenoise合并之前被推迟

解决方案包括使用不同的服务器(如 nginx);使用不同的应用程序(如 whitenoise);或直接使用静态视图而不是 staticfiles 应用程序(有关一些方法,请参阅此问题)。


推荐阅读