如何使用 JSF 2 h:outputStylesheet 实现“CSS 版本控制”(解决缓存问题)?

Posted

技术标签:

【中文标题】如何使用 JSF 2 h:outputStylesheet 实现“CSS 版本控制”(解决缓存问题)?【英文标题】:How can I implement "CSS versioning" (to solve cache issues) using JSF 2 h:outputStylesheet? 【发布时间】:2011-05-15 04:16:07 【问题描述】:

我开始使用 JSF 2,所以我想尝试一下 h:outputStylesheet。它工作正常,但后来我尝试应用“模式”或将查询字符串添加到请求中的技巧,该请求会随着文件版本的变化而改变,以强制浏览器获取更改。

类似what is used here。

很遗憾,我没能做到。实际上,当使用该标记时,它不会生成一个简单的 URL,而是生成一个已经具有查询字符串的计算 URL。我在规范和here 中都找到了一些关于 JSF 2 中资源版本控制的信息,但它似乎指的是资源的多个版本,这不是我需要的。

当然,我总是可以返回不使用新标签。但我想在这里分享这个以供讨论。

更新 1 - 一些例子:

我尝试过的是这样的:

<h:outputStylesheet library="css" name="estilo.css?v=1" target="head"/>

呈现为:

<link type="text/css" rel="stylesheet" href="RES_NOT_FOUND" />

描述性很强。 ;-)

我试图得到的是这样的:

<link rel="stylesheet" type="text/css" href="../css/estilo.css?v=1"/>

其中,使用JSP,我曾经这样说:

<link rel="stylesheet" type="text/css"
 href="<c:url value='/css/estilo.css?v=$initParam.version'/>"/>

【问题讨论】:

你能发布一个你尝试过的例子吗? :) 对此非常好奇。这个特性应该捆绑在每个 Web 框架中。您是否已经在静态资源中添加了 expires HTTP 标头,或者为什么需要这个(否则客户端总是会请求检查文件是否已更改,如果有则更新......不是吗)? @Tuuka:这在某种程度上是一种开发具有动态内容的网络应用程序的技巧。如果您更改“estilo.css”中的某些内容并发布新版本,那么最近访问过您的用户可能不会立即下载新版本。这对 JS 来说更糟,因为它可能会破坏功能性。这个“技巧”使用浏览器使用查询字符串来决定是否下载资源的事实。所以查询字符串(可以是任何字符串)实际上什么都不做。您只需要在内容更改时更改它。并且很容易更改 URL,因为您已经在生成 html 我非常同意这一点。我正要在 Mojarra 项目页面上报告增强请求,但由于其未来迁移到另一个站点,它目前已被禁用。我有一个理论来解决这个问题,但我必须先自己尝试一下。 @Sergi @BalusC 是的,但是浏览器不是每次都创建请求吗?我不知道服务器或浏览器如何将缓存文件与请求的一个浏览器进行比较,但如果有变化(文件大小、一些哈希值,我不知道),浏览器应该下载新的那一个。因此,我认为在其他情况下不需要这样做,除非您设置了过期的 HTTP 标头并生效,并且浏览器甚至不会像通常那样执行检查请求。对吗? 【参考方案1】:

面对同样的挑战,我最终扩展了javax.faces.application.ResourceHandlerWrapper and javax.faces.application.ResourceWrapper 以将“&v=x.y.z”附加到ResourceWrapper#getRequestString() 的结果中。

我看到了 Primefaces 和 Openfaces 实现的这种解决方案。 看看源码就知道了

org.primefaces.application.PrimeResourceHandler#createResource(String resourceName, String libraryName)

org.primefaces.application.PrimeResource#getRequestPath()

Available here.

不要忘记将你的实现添加到 faces-config.xml:

<application>
  <resource-handler>your.package.YourResourceHandlerWrapper</resource-handler>
</application>

【讨论】:

以上是关于如何使用 JSF 2 h:outputStylesheet 实现“CSS 版本控制”(解决缓存问题)?的主要内容,如果未能解决你的问题,请参考以下文章

html 如何使用JSF 2实现简单聊天

如何在 JSF 2.0 中使用 jQuery

如何在 JSF 2.0 中重定向

如何使用 JSF 2 h:outputStylesheet 实现“CSS 版本控制”(解决缓存问题)?

JSF 2.0 验证码如何工作

如何在 JSF 2.0/2.1 中用 CDI 替换 @ManagedBean / @ViewScope