乱世@小熊 2008-09-23 03:07 采纳率: 25%
浏览 1097

如何强制浏览器重载已缓存的 css / js 文件?

I have noticed that some browsers (in particular, Firefox and Opera) are very zealous in using cached copies of .css and .js files, even between browser sessions. This leads to a problem when you update one of these files but the user's browser keeps on using the cached copy.

The question is: what is the most elegant way of forcing the user's browser to reload the file when it has changed?

Ideally the solution would not force the browser to reload the file on every visit to the page. I will post my own solution as an answer, but I am curious if anyone has a better solution and I'll let your votes decide.

Update:

After allowing discussion here for a while, I have found John Millikin and da5id's suggestion to be useful. It turns out there is a term for this: auto-versioning.

I have posted a new answer below which is a combination of my original solution and John's suggestion.

Another idea which was suggested by SCdF would be to append a bogus query string to the file. (Some Python code to automatically use the timestamp as a bogus query string was submitted by pi.). However, there is some discussion as to whether or not the browser would cache a file with a query string. (Remember, we want the browser to cache the file and use it on future visits. We only want it to fetch the file again when it has changed.)

Since it is not clear what happens with a bogus query string, I am not accepting that answer.

转载于:https://stackoverflow.com/questions/118884/how-to-force-browser-to-reload-cached-css-js-files

  • 写回答

30条回答 默认 最新

  • elliott.david 2008-09-23 03:07
    关注

    Update: Rewritten to incorporate suggestions from John Millikin and da5id. This solution is written in PHP, but should be easily adapted to other languages.

    Update 2: Incorporating comments from Nick Johnson that the original .htaccess regex can cause problems with files like json-1.3.js. Solution is to only rewrite if there are exactly 10 digits at the end. (Because 10 digits covers all timestamps from 9/9/2001 to 11/20/2286.)

    First, we use the following rewrite rule in .htaccess:

    RewriteEngine on
    RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
    

    Now, we write the following PHP function:

    /**
     *  Given a file, i.e. /css/base.css, replaces it with a string containing the
     *  file's mtime, i.e. /css/base.1221534296.css.
     *  
     *  @param $file  The file to be loaded.  Must be an absolute path (i.e.
     *                starting with slash).
     */
    function auto_version($file)
    {
      if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
        return $file;
    
      $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
      return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
    }
    

    Now, wherever you include your CSS, change it from this:

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

    To this:

    <link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
    

    This way, you never have to modify the link tag again, and the user will always see the latest CSS. The browser will be able to cache the CSS file, but when you make any changes to your CSS the browser will see this as a new URL, so it won't use the cached copy.

    This can also work with images, favicons, and JavaScript. Basically anything that is not dynamically generated.

    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?