django - 许多 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 + R
或shift + F5
)。
我尝试研究此滚降,但找不到任何信息。我认为这是谷歌浏览器(我正在使用的浏览器)内置的东西,以在页面没有变化时节省带宽,但我的状态页面最多只有几千字节,并且 304 响应已经节省了一点带宽,如果有一种方法可以完全禁用这种用于生产的滚降,这将是理想的。
无论如何,任何关于我为什么看到这种行为/它来自哪里的信息都将不胜感激,因为我似乎找不到任何关于它的文档。我发现的最接近的内容来自 Google 的关于缓存的开发人员文档。它提到了定义最大年龄和无缓存行为的能力,所以我可以强制客户端每分钟重新下载 status.html ,但这似乎很混乱。虽然这在我的特定场景中可以工作,因为 status.html 最多只有几千字节,但只要禁用这种滚降行为就可以解决问题,并且会降低不必要的带宽。
解决方案
这里的问题是响应status.html
没有明确的缓存过期标头。在没有这样的标头的情况下,浏览器可以自由地使用自己的算法(例如您看到的滚降)来选择过期时间。来自RFC 7234:
由于原始服务器并不总是提供明确的过期时间,缓存可以在未指定明确时间时分配启发式过期时间......本规范不提供特定算法。
所以解决方案很简单:分配一个显式的缓存过期时间。
不幸的是,使用 Django 的 staticfiles 应用程序实现此解决方案并非易事。这个应用程序更好的默认设置是根本不缓存结果,但该解决方案在与whitenoise合并之前被推迟。
解决方案包括使用不同的服务器(如 nginx);使用不同的应用程序(如 whitenoise);或直接使用静态视图而不是 staticfiles 应用程序(有关一些方法,请参阅此问题)。
推荐阅读
- visual-studio-code - VScode webview 扩展 api
- android - FLUTTER:任务':app:compileFlutterBuildDebug'执行失败无法创建父目录
- c++ - 声明与 void 不兼容
- c++ - 函数调用的参数太多,预期单个参数“nums”,有 3 个参数
- windows-installer - 对 BizTalk 生成的 MSI 文件进行产品版本控制
- c# - localhost websocket (wss://localhost:xyz/) 并非对所有用户都可用
- python - 如何在 Jupyter Notebook 中导入特定版本的 numpy?
- java - 我的数组没有到达数组的最后一个元素
- react-native - React Native Linking 抛出错误:无法打开 URL:
- java - 文本上方的 JMenu 图标