如何在客户端强制刷新CSS缓存?


61

假设我们更改了模块的许多功能(模板,布局,CSS),并将这些更改移至生产现场,但是许多客户已将CSS缓存在其浏览器中。所以这是一个问题。如何强制刷新客户端的CSS缓存并避免文件重命名(styles.css-> styles-v2.css)。有一种逻辑方法,但是在Magento中不起作用,因为它会检查文件是否存在(通过此方法对JS文件的工作方式),请参见下文:

<action method="addCss">
    <stylesheet>css/styles.css?1</stylesheet>
</action>  

有任何想法吗?

Answers:


37

解决此问题的一种方法是启用CSS合并。然后,您可以清除缓存,并使用新的文件名创建一个新的合并文件。

System -> Configuration -> Developer -> CSS settings -> Merge CSS Files

据我所知,即使基础文件发生了更改,合并CSS文件的哈希码也保持不变-仅在将新文件添加到合并文件集中时,哈希才会更改。-@亚历克斯

解决此问题的另一种方法是不使用layout.xml,

只是把它们放在你的 page/html/head.phtml

或创建一个包含<style>带有版本号标签的代码块,并将其放入XML头部,这样您就可以仅将其加载到特定页面上,并且仍然坚持使用XML布局。


10
据我所知,即使基础文件发生了更改,合并CSS文件的哈希码也保持不变-仅在将新文件添加到合并文件集中时,哈希才会更改。
Alex

@Alex不知道,这是有道理的。
里克·库珀斯

4
我最近没有看过,但是在过去,如果在不同页面上加载不同的CSS / JS,则CSS / JS的编译似乎实际上为您的网站增加了额外的“重量”。它为每个唯一的脚本集创建了一个不同的编译版本。这意味着被编译进来的较大文件实际上被多次下载。
彼得·奥卡拉汉

@cags-是的,基本上,在这种情况下,最小化并允许所有CSS / JS文件下载一次是唯一有效的速度增强措施。
Fiasco Labs 2013年

有时这可能会更改CSS行为,至少对于我来说,至少在Magento 1.9.2.1
Goose


10

github'Magento Cachebuster'上有一个免费扩展程序可以完全做到这一点。它是

https://github.com/gknoppe-guidance/magento-cachebuster

该模块通过将文件的时间戳添加到文件名中来自动更改Magento为静态文件创建的URI,从而提供缓存无效化:

之前:http : //www.example.com/js/varien/js.js 之后:http : //www.example.com/js/varien/js.1324429472.js


2
此模块为每个响应解析HTML以添加时间戳,这可能会损害性能。github.com/fbrnc/Aoe_JsCssTstamp以更高效的方式完成了同样的工作,但是它需要重写设计包模型来完成它,而Cachebuster仅使用观察者。
Fabian Schmengler,2015年

10

我为此使用自己的扩展程序Speedster Advanced。但是基本原理是,合并的css和js文件的名称包括最后修改的文件的时间戳(请参见)Mage_Core_Model_Design_Package::getMergedCssUrl()。每当您编辑任何一个css文件时,都会创建一个新文件名,从而使浏览器请求新文件,而不是重新使用缓存的版本。由于可能会缓存您的磁头块,因此需要刷新Magento缓存。


福曼·斯皮斯特(Fooman Speedster)获得我的投票极大的扩展
Bobadevv '16

8

我还为css文件实现了缓存清除器。我猜最好的方法是扩展Mage_Page_Block_Html_Head并覆盖下面的函数,并用所需的更改更新$ skinItems数组。

protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
{
    $designPackage = Mage::getDesign();
    //$skinItems: contains all css
    foreach ($skinItems as $params => $rows) {
        foreach ($rows as $key=>$name) {
            $file = $designPackage->getFilename($name, array('_type' => 'skin'));
            $skinItems[$params][$key] = $name . "?fmt=" . filemtime($file);
        }
    }
    return parent::_prepareStaticAndSkinElements($format, $staticItems, $skinItems, $mergeCallback);

}

从这里得到了灵感。资源


1
这将不起作用,外观文件将始终退回到基本/默认值,因为找不到带有附加查询字符串的文件名。
BlueC

您的注释“找不到带有附加查询字符串的文件名”,这就是我们想要的,那将破坏高速缓存并迫使高速缓存服务器获取新副本。
Ahad Ali

1
不,根本不是这样。您正在更改$ skinItems数组中元素的值,然后将它们传递回父_prepareStaticAndSkinElements()方法。该父方法将在每个修改后的项目上调用Mage :: getDesign()-> getSkinUrl(),由于无法在文件系统上找到带有?fmt = xxx的文件,该方法将始终回退到基本/默认值。
BlueC

不确定他的实现方式,但是从底部获得的灵感绝对可以按照您的期望完全起作用,github.com / mklooss / Loewenstark_Head
Goose

8

有一个简单但麻烦的解决方法,不需要任何插件,而仅使用Magento内置功能-如果您只需要在现有站点上快速进行操作而又不想冒险安装更多代码,则非常有用。

这个想法是,您可以使用合并的CSS系统来生成缓存清除文件名。

由于合并的CSS文件名是所有合并在一起的文件的哈希,因此您只需在主题中添加一个额外的空白css文件,并在名称上添加日期戳即可。

所以:

  1. 在配置>高级>开发人员中打开合并CSS文件
  2. 在主题布局中,找到将CSS文件添加到头部(通常为page.xml)并添加一个额外的样式表文件的位置,只要名称唯一,即可将其命名为任意名称,例如 <action method="addCss"><stylesheet>css/cachebust_091014.css</stylesheet></action>
  3. 在您的皮肤CSS文件夹中,使用该名称创建一个新的CSS文件,对于文件内容,我只添加了一条注释,说明该文件的用途

现在推送并刷新magento缓存,合并的CSS文件现在将具有不同的名称,并且缓存将被破坏!

每次您要破坏缓存时都需要更改该文件名,这很麻烦,但是除了内置的Magento功能外,它不需要任何其他操作,因此如果发现卡住并需要快速修复,这非常方便!


7

=>而不使用此代码:

<action method="addCss">
    <stylesheet>css/styles.css?1</stylesheet>
</action>

=>尝试使用以下代码:

<reference name="head">
    <block type="core/text" name="foocss">
        <action method="setText">
            <css><![CDATA[<link rel="stylesheet" type="text/css" href="foo.css?1" media="all" />]]></css>
        </action>
    </block>
</reference>

但这不是很好...


有趣的主意:)
尼克,

这是短期检查的好主意。
Jay El-Kaake 2015年

4

我找到了一个模块,该模块会将查询字符串附加到xml布局中所有CSS和JS的末尾。查询字符串可从管理员配置。

https://github.com/mklooss/Loewenstark_Head

基本思想是重写_prepareStaticAndSkinElements以包括查询字符串,如模块所示,如下所示。

protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
{
    $version = Mage::getStoreConfig("design/head/meta_version_tag");
    $format = sprintf($format, "%s?v{$version}", "%s");
    return parent::_prepareStaticAndSkinElements($format, $staticItems, $skinItems, $mergeCallback);
}

3

如果我理解您提出的问题的解决方案,则可以对核心文件进行一些修改不要实际编辑核心文件):

法师/页面/块/HTML/Head.php

在第198行中添加?v = 1之类的内容,以便所有css文件都附加以下内容:

$html .= $this->_prepareStaticAndSkinElements('<link rel="stylesheet" type="text/css" href="%s?v=1"%s />' . "\n",


2

我为此构建了一个免费模块:

http://www.magentocommerce.com/magento-connect/frontend-flush-2048.html

请让我知道它是否无法按预期工作,但是我已经构建了它,以便如果串联文件之一的内容已更改,则合并的js和css文件将具有不同的哈希值。默认情况下,Magento仅在其中一个包含文件的文件名已更改的情况下更改组合文件的哈希。

更新

我还为那些相信它的人免费提供了一个简单的缩小模块。

http://www.magentocommerce.com/magento-connect/minify-7771.html


该模块不起作用...
SIBHI S 2015年

2

Fabrizio Branca创建了一个非常不错的模块,该模块完全执行您感兴趣的事情。它称为AOE_JsCSSTStamp。它能做什么?它为CSS和JS资源都添加了时间戳。刷新CSS / JS缓存时,将重新创建时间戳。

浏览器将看到不同的文件名-这就是为什么它将再次重新下载资源并以最新鲜的资源提供而不是缓存在浏览器中的原因。


1

只需在Mage_Page_Block_Html_Head中编辑方法getCssJsHtml然后在CSS编辑后几天添加这样的字符串,就可以了。

// static and skin css
        $html .= $this->_prepareStaticAndSkinElements('<link rel="stylesheet" type="text/css" href="%s?foo=WHAT_YOU_WANT_HERE"%s />' . "\n",
            empty($items['js_css']) ? [] : $items['js_css'],
            empty($items['skin_css']) ? [] : $items['skin_css'],
            $shouldMergeCss ? [Mage::getDesign(), 'getMergedCssUrl'] : null
        );

1

几年后,由于找不到任何不会合并文件且非常简单的有用扩展,我创建了自己的扩展。主要思想是刷新缓存后,它将更新时间戳记。因此,换句话说-当您更改某些内容时css/js,只需刷新缓存和时间戳即可更新。

源代码在这里-> https://github.com/archonkulis/ANSolutions_CssJsTimestamp

适用于1.9+版本。虽然不确定较旧的版本,但很可能应该也能正常工作。


-2

使用新名称(themev2)制作主题的副本-外观和应用程序/设计等。然后在admin中选择新主题。


不,您永远不会那样做。这确实是一种不好的方式
马吕斯

为什么不?这样,如果新版本出了问题,您可以快速返回到旧版本。如果您使用较长的浏览器缓存时间和/或CDN来服务CSS(以及可能还需要刷新/无效的js),则这是迄今为止最简单的方法。
Phil Lee

如果出现问题,请回滚,其中应包含另一个(旧的)文件名,因此不需要更改配置(读取为包/主题)
Fabian Blechschmidt 2014年

我不知道您如何进行部署,但是这样一来,我必须保留旧的主题文件夹,直到我更改包/主题的值,或者创建一个脚本来更新安装时的值。另外,如果我在不同的时间段设置了不同的主题,它们可能会受到影响。到目前为止,复制大量文件是bot最简单的方法。例如,安装此程序:github.com/jreinke/magento-suffix-static-files更加容易。您要做的就是在每次部署后在后端更改一个数字。
马里乌斯

甚至不要这样想!
林托·乔治
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.