我已经构建了一个基于指令的AngularJS HTML5应用程序。每个指令都将使用templateUrl
语法从另一个文件加载它的模板。
该应用程序是一个单页面应用程序,让我们假装它可以通过http://prod/index.html
访问,当加载该页面时,指令将加载http://prod/partials/directive-a.html
在将新版本的网站推送到我的生产环境时,我遇到了问题。浏览器继续使用先前版本的缓存资产。
例如,如果我导航到http://prod
,则会显示以前版本中的所有资产。如果我强制刷新页面(CTRL+F5
),将从服务器重新加载index.html页面并反映任何更改。
不导致浏览器刷新partials/directive-a.html
。因此,新的index.html
页面仍会显示旧的directive-a.html
。
如果我导航到浏览器地址栏中的完整部分HTML文件(partials/directive-a.html
),则会向我显示旧版本的部分。通过对部分页面进行硬刷新,将显示部分页面的正确(新)版本,并在重新加载index.html
上的指令时进行更新。
我可以使用哪些机制来阻止部分缓存?
我见过关于在查询参数中添加时间戳的评论,但这似乎过于笨重地放在我的所有指令和路由上。
答案 0 :(得分:2)
@Duncan为您提供了处理模板的绝佳方式,但我认为这不是唯一的问题。请记住缓存js
,css
和index.html
。
简单解决方案
如果您想要缓存问题的简单(几乎理想)解决方案,您可以强制服务器在第一次请求时设置会话cookie(对于index.html
)。浏览器会将html
和js
缓存为会话长度。您仍然可以获得部分缓存支持而且没有任何问题。
# First response header will set session id:
Set-Cookie:JSESSIONID=0E9AAA7D661A3E100C8EE9F421541B91; Expires=Sun, 29-Jan-2017 14:25:25 GMT; Path=/; HttpOnly
# Next browser request will contain session id from first response.
Cookie:JSESSIONID=0E9AAA7D661A3E100C8EE9F421541B91
复杂的解决方案
您应该考虑使用自定义标头来提供Angular资源。您可以在mod_expires
内使用apache
。
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType application/javascript "access plus 0 seconds"
ExpiresByType text/css "access plus 0 seconds"
...
此解决方案的问题是丢失缓存机制。返回用户不会更快地加载您的网站,您的服务器将体验更多的使用。你可以遇到性能问题。
您可以通过构建机制来改进此解决方案:
application.js
application.js
application.js
更改为application.[unique-id].js
index.html
同样适用于css
和第三方图书馆。
之后你就可以改变了
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
...
显然,有基于Grunt
或Gulp
的自动化解决方案。就个人而言,我可以推荐https://github.com/yeoman/generator-angular
这两种解决方案都适用于我目前的应用程序。
答案 1 :(得分:1)
我还没有通过测试来查看这是否有效(通过快速Google搜索找到),尽管我认为应该这样做。它正在装饰$http
服务,以便任何请求都有一个缓存添加到URL的缓存。您可能希望将逻辑更改为仅装饰'partials/'
文件夹中的URL。
anglar.module('myApp',['ui']).config(["$provide", function($provide) {
return $provide.decorator("$http", ["$delegate", function($delegate) {
var get = $delegate.get;
$delegate.get = function(url, config) {
// Check is to avoid breaking AngularUI ui-bootstrap-tpls.js: "template/accordion/accordion-group.html"
if (!~url.indexOf('template/')) {
// Append ?v=[cacheBustVersion] to url
url += (url.indexOf("?") === -1 ? "?" : "&");
url += "v=" + cacheBustVersion;
}
return get(url, config);
};
return $delegate;
}]);
}]);
来自https://gist.github.com/ProLoser/6181026
或者将所有部分编译成单个templates.js
文件,该文件填充模板缓存,然后根本没有模板的实际http请求。如果您使用gulp
构建应用程序,则可以使用各种插件模块(例如gulp-angular-templatecache
或gulp-angular-templates
)。