Django 仅在硬刷新(shift + 刷新)后才加载正确的页面,因为 service worker 不会在每次刷新时使缓存失效
Django loads correct page only after a hard refresh (shift + refresh) because the service worker is not invalidating the cache every refresh
我有一个 Django 应用程序,它使用条件逻辑来确定要在导航栏中显示的内容。例如,如果用户未通过身份验证 --> show "Login",else --> "show username." 它在开发中完美运行,但在我的 apache 服务器上,它似乎总是执行 "else"阻止,除非我在 safari 和 chrome 中执行 shift+refresh。它似乎只在我的索引页面上执行此操作,在应用程序的其他页面上 if/else 按预期工作。
base.html
{% if user.is_authenticated %}
<a href="{% url 'login-signout' %}" id="account-link">
{% if user.username %}
{{user.username | capfirst }}
{% elif user.first_name %}
{{user.first_name | capfirst }}
{% else %}
Account
{% endif %}
</a>
{% else %}
<a href="{% url 'login-signup' %}" id="account-link">
Login
</a>
{% endif %}
我试图只获取项目的新副本,但得到的结果相同。知道为什么会这样吗?
编辑以更新问题
因此,在评论中建议的修复之后,我能够确定问题是服务工作者正在查看旧缓存而不是每次刷新都获取新副本。
serviceworker.js
var staticCacheName = "django-pwa-v" + new Date().getTime();
// caches on install
self.oninstall = function (evt) {
evt.waitUntil(caches.open(staticCacheName).then(function (cache) {
return Promise.all(['/', 'main/home.html'].map(function (url) {
return fetch(new Request(url, { redirect: 'manual' })).then(function (res) {
return cache.put(url, res);
});
}));
}));
};
// Clear cache on activate
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(cacheName => (cacheName.startsWith("django-pwa-")))
.filter(cacheName => (cacheName !== staticCacheName))
.map(cacheName => caches.delete(cacheName))
);
})
);
});
// serve from cache
self.onfetch = function (evt) {
var url = new URL(evt.request.url);
if (url.pathname != '/' && url.pathname != 'main/home.html') return;
evt.respondWith(caches.match(evt.request, { cacheName: staticCacheName }));
};
为了完全避免这个问题,我在 templates/main/offline.html 中构建了一个名为离线的模板,我可以只缓存该页面并仅在离线时显示该页面而不是尝试缓存主应用程序页面吗?
这不是 django 问题,而是浏览器问题。您的浏览器正在缓存页面以缩短加载时间。浏览器选择缓存哪些页面取决于浏览器,但在您的情况下似乎是主页。浏览器也会做出明智的决定来缓存页面的 css、js、header,因为它可能不会改变。
注意:- 如果您正在使用像 memcache 或 varnish 这样的服务器端缓存,则必须在每次更新后使缓存失效。
更新
在弄清楚它的缓存失效问题后,我建议,请阅读官方 W3 附属网站上的文档,它有关于如何使缓存失效以及如何为离线页面提供服务的所有答案。
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Offline_Service_workers
我有一个 Django 应用程序,它使用条件逻辑来确定要在导航栏中显示的内容。例如,如果用户未通过身份验证 --> show "Login",else --> "show username." 它在开发中完美运行,但在我的 apache 服务器上,它似乎总是执行 "else"阻止,除非我在 safari 和 chrome 中执行 shift+refresh。它似乎只在我的索引页面上执行此操作,在应用程序的其他页面上 if/else 按预期工作。
base.html
{% if user.is_authenticated %}
<a href="{% url 'login-signout' %}" id="account-link">
{% if user.username %}
{{user.username | capfirst }}
{% elif user.first_name %}
{{user.first_name | capfirst }}
{% else %}
Account
{% endif %}
</a>
{% else %}
<a href="{% url 'login-signup' %}" id="account-link">
Login
</a>
{% endif %}
我试图只获取项目的新副本,但得到的结果相同。知道为什么会这样吗?
编辑以更新问题 因此,在评论中建议的修复之后,我能够确定问题是服务工作者正在查看旧缓存而不是每次刷新都获取新副本。
serviceworker.js
var staticCacheName = "django-pwa-v" + new Date().getTime();
// caches on install
self.oninstall = function (evt) {
evt.waitUntil(caches.open(staticCacheName).then(function (cache) {
return Promise.all(['/', 'main/home.html'].map(function (url) {
return fetch(new Request(url, { redirect: 'manual' })).then(function (res) {
return cache.put(url, res);
});
}));
}));
};
// Clear cache on activate
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(cacheName => (cacheName.startsWith("django-pwa-")))
.filter(cacheName => (cacheName !== staticCacheName))
.map(cacheName => caches.delete(cacheName))
);
})
);
});
// serve from cache
self.onfetch = function (evt) {
var url = new URL(evt.request.url);
if (url.pathname != '/' && url.pathname != 'main/home.html') return;
evt.respondWith(caches.match(evt.request, { cacheName: staticCacheName }));
};
为了完全避免这个问题,我在 templates/main/offline.html 中构建了一个名为离线的模板,我可以只缓存该页面并仅在离线时显示该页面而不是尝试缓存主应用程序页面吗?
这不是 django 问题,而是浏览器问题。您的浏览器正在缓存页面以缩短加载时间。浏览器选择缓存哪些页面取决于浏览器,但在您的情况下似乎是主页。浏览器也会做出明智的决定来缓存页面的 css、js、header,因为它可能不会改变。 注意:- 如果您正在使用像 memcache 或 varnish 这样的服务器端缓存,则必须在每次更新后使缓存失效。
更新
在弄清楚它的缓存失效问题后,我建议,请阅读官方 W3 附属网站上的文档,它有关于如何使缓存失效以及如何为离线页面提供服务的所有答案。
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Offline_Service_workers