如何强制 Firefox 绕过 Angular.JS 部分的 BFCache?
How to force Firefox to bypass BFCache for Angular.JS partials?
我正在处理 Angular.js 页面并正在更改 html 'partial'。刷新页面会导致 Firefox 正确地从服务器重新请求主 html 页面,但是在客户端呈现的后续 'partial' 模板永远不会被重新请求,而是从 BFCache 中获取,因此更改未检测到这些文件。
来自 Firebug 的屏幕截图:
我可以通过开发服务器 (Django) 确认从未请求过这些部分。
我试过各种刷新方式,包括 Reload Plus 扩展。
这些都不太理想,但似乎有两个选项可以解决问题。
一个是 Clear Cache 插件,可以将其配置为清除磁盘和内存缓存并重新加载当前选项卡。我不确定这是否会完全清除缓存或只清除当前选项卡域的缓存,但它可能是整个缓存。
另一种是在firebug中禁用浏览器缓存:
我不确定这是否只是禁用当前页面、当前域或所有地方的缓存。
有一个'Reload this page and everything referenced by this page'选项还是不错的。
我会在你的模板中设置一个标志来添加一个简单的 onunload 函数,如下所示:
{% if CLEARBFCACHE %} <body onunload="myFunction()"> {% endif %}
然后在开发时设置 CLEARBFCACHE = 1(在 settings.py)。
如果您需要测试生产集 CLEARBFCACHE = 0 然后部署到您的暂存服务器或(如果您没有单独的服务器)我相信您可以将 url 从 127.0.0.1 更改为locahost 让 Firefox 认为它是一个不同的站点。
另一种选择是让您的开发 Web 服务器为至少 html 个文件发送 Cache-Control header:
Cache-Control: no-cache, max-age=0, must-revalidate, no-store
来源:How to Defeat the Browser Back Button Cache
那么开发服务器提供的所有文件将永远不会被缓存,但是来自例如CDN 将被缓存,因此您不必在每次刷新时检索它们。
因为您正在制作单页应用程序。所以正确的解法应该是:
(1)设置物理页面(即主页)为"Cache-Control: No-cache"。
物理页要小,因为逻辑页都是动态加载JavaScript,所以加载物理页本身应该快
(2)对于"partial"页面(即逻辑页面),每次发布新版本时更改文件夹名称,
例如:部署新版本时,假设物理页面为index.html
在index.html里面,所有JavaScript、css和angularJs模板文件都在文件夹asset-{{TimeStamp}}中。
因为 index.html 没有缓存,所以浏览器总是获取最新的 index.html。
因为所有 JS 、 css 和其他模板 html 文件都位于与上一版本不同的文件夹中。
因此浏览器将从新文件夹而不是缓存中加载所有文件。
您可以创建一个构建过程来自动执行此操作:
搜索 index.html 中的所有 js , css 文件并将文件夹名称 asset/** 替换为 asset-{{TimeStamp}}/**,然后将所有文件从 asset 复制到 asset-{{TimeStamp}}文件夹
现在您没有头痛的缓存问题,但浏览器确实利用本地缓存来加速您的网页。
(3)为angularJs模板文件,因为也是JS加载的,
所以我们强烈建议您使用相对路径(与当前 运行 JS 代码相关)来获取它。
一些示例 JS 代码如下:
function _getCurrentJSPath() {
var scripts = document.getElementsByTagName("script");
var currentFile = scripts[scripts.length - 1].src;
var currentPath = currentFile.substr(0, currentFile.lastIndexOf('/')) + "/";
return currentPath;
}
...
templateUrl: _getCurrentJSPath() + 'currencyField.html',
另一种选择是按以下方式包含部分内容:
angular
.module("app")
.directive("appPartial", function () {
return {
templateUrl: "partials/partial1.htm"+getTempStr(),
restrict: "E",
scope: {},
controller: PartialController,
controllerAs: "vm"
}
});
function getTempStr(){
// dev
return "?a=" + (new Date().getTime()).toString();
// prod
//return "";
}
这样每次加载部分时都不会存储在 BFCache 中。
要在生产环境中使用 BFCache,您可以取消注释 'return ""' 行而不是其他 return 行。
我正在处理 Angular.js 页面并正在更改 html 'partial'。刷新页面会导致 Firefox 正确地从服务器重新请求主 html 页面,但是在客户端呈现的后续 'partial' 模板永远不会被重新请求,而是从 BFCache 中获取,因此更改未检测到这些文件。
来自 Firebug 的屏幕截图:
我可以通过开发服务器 (Django) 确认从未请求过这些部分。
我试过各种刷新方式,包括 Reload Plus 扩展。
这些都不太理想,但似乎有两个选项可以解决问题。
一个是 Clear Cache 插件,可以将其配置为清除磁盘和内存缓存并重新加载当前选项卡。我不确定这是否会完全清除缓存或只清除当前选项卡域的缓存,但它可能是整个缓存。
另一种是在firebug中禁用浏览器缓存:
我不确定这是否只是禁用当前页面、当前域或所有地方的缓存。
有一个'Reload this page and everything referenced by this page'选项还是不错的。
我会在你的模板中设置一个标志来添加一个简单的 onunload 函数,如下所示:
{% if CLEARBFCACHE %} <body onunload="myFunction()"> {% endif %}
然后在开发时设置 CLEARBFCACHE = 1(在 settings.py)。
如果您需要测试生产集 CLEARBFCACHE = 0 然后部署到您的暂存服务器或(如果您没有单独的服务器)我相信您可以将 url 从 127.0.0.1 更改为locahost 让 Firefox 认为它是一个不同的站点。
另一种选择是让您的开发 Web 服务器为至少 html 个文件发送 Cache-Control header:
Cache-Control: no-cache, max-age=0, must-revalidate, no-store
来源:How to Defeat the Browser Back Button Cache
那么开发服务器提供的所有文件将永远不会被缓存,但是来自例如CDN 将被缓存,因此您不必在每次刷新时检索它们。
因为您正在制作单页应用程序。所以正确的解法应该是:
(1)设置物理页面(即主页)为"Cache-Control: No-cache"。 物理页要小,因为逻辑页都是动态加载JavaScript,所以加载物理页本身应该快
(2)对于"partial"页面(即逻辑页面),每次发布新版本时更改文件夹名称,
例如:部署新版本时,假设物理页面为index.html
在index.html里面,所有JavaScript、css和angularJs模板文件都在文件夹asset-{{TimeStamp}}中。 因为 index.html 没有缓存,所以浏览器总是获取最新的 index.html。 因为所有 JS 、 css 和其他模板 html 文件都位于与上一版本不同的文件夹中。 因此浏览器将从新文件夹而不是缓存中加载所有文件。
您可以创建一个构建过程来自动执行此操作: 搜索 index.html 中的所有 js , css 文件并将文件夹名称 asset/** 替换为 asset-{{TimeStamp}}/**,然后将所有文件从 asset 复制到 asset-{{TimeStamp}}文件夹
现在您没有头痛的缓存问题,但浏览器确实利用本地缓存来加速您的网页。
(3)为angularJs模板文件,因为也是JS加载的, 所以我们强烈建议您使用相对路径(与当前 运行 JS 代码相关)来获取它。 一些示例 JS 代码如下:
function _getCurrentJSPath() {
var scripts = document.getElementsByTagName("script");
var currentFile = scripts[scripts.length - 1].src;
var currentPath = currentFile.substr(0, currentFile.lastIndexOf('/')) + "/";
return currentPath;
}
...
templateUrl: _getCurrentJSPath() + 'currencyField.html',
另一种选择是按以下方式包含部分内容:
angular
.module("app")
.directive("appPartial", function () {
return {
templateUrl: "partials/partial1.htm"+getTempStr(),
restrict: "E",
scope: {},
controller: PartialController,
controllerAs: "vm"
}
});
function getTempStr(){
// dev
return "?a=" + (new Date().getTime()).toString();
// prod
//return "";
}
这样每次加载部分时都不会存储在 BFCache 中。
要在生产环境中使用 BFCache,您可以取消注释 'return ""' 行而不是其他 return 行。