用过七牛cdn的同学大概有过这样的经历:在主题里更新了一个js脚本或者css文件后,但是却无法更新七牛那里的缓存文件,因为js脚本或者css文件后面往往添加了?ver=xxx这样的版本号。本文介绍下问题产生的原因及解决办法。

版本号产生原因

这是因为WordPress中使用wp_enqueue_script()和wp_enqueue_style()引入js脚本和css样式表时,会生成一个版本号,如果你不亲自指定,版本号会是WordPress的版本号,比如3.7.1。版本号有好处,可以强制浏览器更新脚本,但有些SEO检测工具会认为带有版本号是非静态化的表现,同样给七牛cdn的缓存更新带来麻烦。

解决办法

在主题的functions.php中加入如下代码,就可以去除版本号:

function sb_remove_script_version( $src ){
    $parts = explode( '?', $src );
    return $parts[0];
}
add_filter( 'script_loader_src', 'sb_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', 'sb_remove_script_version', 15, 1 );

要注意的是,只有通过WordPress的方式引入脚本才会产生版本号,如果自己硬编码进去,这段代码是不起作用的,当然,不推荐硬编码js文件。

小结

本文参考了http://www.solagirl.net/remove-version-string-from-js-css.html这篇文章,确实解决了该问题。

--------------------------------------

WordPress删除版本号的方法

使用WordPress的博主都有一个普遍的意识,就是为了安全而移除WordPress的版本号,以免不良用心的人利用旧版本的漏洞对网站进行攻击。

WordPress会在前端代码head中加入以下代码(3.8是当前网站所使用的WordPress版本号):
<meta name="generator" content="WordPress 3.8" />

有很多方法可以移除WordPress添加的版本号信息,我们先看看几种常见的方式:

方法一(错误):修改WordPress源代码

修改wp-includes/defaults-filter.php,将其中的:

  1. add_action('wp_head', 'wp_generator');

改成:

  1. remove_action('wp_head', 'wp_generator');

相信现在已经没人还傻到去修改WordPress源文件来实现某种功能了吧?下次WordPress更新又得重新修改,实在是累!

方法二(错误):直接删除wp_head()

因为本文开头那段泄漏WordPress版本号的代码,一般是主题文件header.php中的wp_head()函数输出的,并且这个函数会输出一些无用的代码,所以有些人干脆来个痛快,直接把wp_head()函数删掉了事。只是他们没有想过,很多插件/主题会通过这个函数进行一些操作,删掉这个函数将使这些插件/主题无法工作。兴许,下次安装个插件,死活用不了还找不到原因呢!

方法三:remove_action

一个好的方法,也是绝大多数教程提供的方法,是在当前主题的functions.php中添加以下代码:

  1. remove_action('wp_head', 'wp_generator');

这样就可以从网站的head中移除本文开头提到的那段含有版本号的代码。但是,这里我要打击一下各位,最近在露兜博客留言的使用WordPress的站长,几乎没有一个站点能够完全隐藏掉WordPress版本号。打开你们的feed源,如http://example.com/feed,有没有看到这个:

  1. <generator>http://wordpress.org/?v=3.8</generator>

啊啊!3.8不就是WordPress的版本号吗?再随便看看你的一篇文章的网页源代码,是否会看到下面的几段类似代码呢:

  1. <script type='text/javascript' src='/wp-includes/js/comment-reply.min.js?ver=3.8'></script>
  2. <link rel='stylesheet' href='/wp-includes/css/admin-bar.css?ver=3.8' type='text/css' />
  3. <link rel='stylesheet' href='//fonts.googleapis.com/css?family=Handlee&#038;ver=3.8' type='text/css' />

呵呵,又见3.8,其实WordPress不仅会输出本文开头的那段代码,而且会在feed中输出版本号,另外,为了更新缓存,某些css和js结尾也会附上WordPress版本号(如以上第2-3行代码)。

方法四:正确方法

所以,我们还应该移除feed和js/css中的WordPress版本号,在当前主题的functions.php中添加以下代码:

  1. // 同时删除head和feed中的WP版本号
  2. function ludou_remove_wp_version() {
  3.   return '';
  4. }
  5. add_filter('the_generator', 'ludou_remove_wp_version');
  6.  
  7. // 隐藏js/css附加的WP版本号
  8. function ludou_remove_wp_version_strings( $src ) {
  9.   global $wp_version;
  10.   parse_str(parse_url($src, PHP_URL_QUERY), $query);
  11.   if ( !empty($query['ver']) && $query['ver'] === $wp_version ) {
  12.     // 用WP版本号 + 12.8来替代js/css附加的版本号
  13.     // 既隐藏了WordPress版本号,也不会影响缓存
  14.     // 建议把下面的 12.8 替换成其他数字,以免被别人猜出
  15.     $src = str_replace($wp_version, $wp_version + 12.8, $src);
  16.   }
  17.   return $src;
  18. }
  19. add_filter( 'script_loader_src', 'ludou_remove_wp_version_strings' );
  20. add_filter( 'style_loader_src', 'ludou_remove_wp_version_strings' );

另外,在WordPress后台右下角也会显示WordPress版本号,leiming网友提供了:去除此版本号的代码。不过个人觉得,如果开放了后台,从后台的界面风格也很好判断WordPress的版本,毕竟从我使用WordPress至今,WordPress已经换过4次界面了。

当然,如果你还发现有其他地方泄漏WordPress版本号,那么欢迎给我反馈。

-------------------------------

HTML中css和js链接中的版本号

背景

在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、js等,而不必从你的服务器读取,这样在一定程度上加快了网站的打开速度,又可以节约一下你的服务器流量。

问题

现在问题来了,.htaccess设置的css、js缓存都有一个过期时间,如果在访客的浏览器中已经缓存了css、js,在这些css、js缓存未过期之前,浏览器只会从缓存中读取css和js,如果你在服务器上修改了css和js,那么这些更改在回头客的浏览器中是不会有变化的,除非回头客按了Ctrl + F5刷新了你的网站页面或者手动清空了浏览器的缓存。一个网站的访客成千上万,回头客也会有不少,你不可能在更新css后让每个访客都刷新一下缓存吧,那么这个问题你会怎么处理呢?

处理办法

1.更改css文件名:其实解决这个问题很简单,缓存是通过文件名标记缓存的内容的。在你更新了网站的css文件内容后,在更换一下css的文件名就可以了。如原先html中的css调用语句如下:

<link rel="stylesheet" href=“http://www.example.com/style.css” type="text/css" media="screen" />

改一下css文件名就可以了:

<link rel=“stylesheet” href="http://www.example.com/index.css" type="text/css" media="screen" />

另外一种从更改css文件名的方法是将版本号写到文件名中,如:

<link rel="stylesheet" href="http://www.example.com/index.v2011.css" type="text/css" media="screen"/>

css文件更新后,改一下文件名中的版本号即可:

<link rel="stylesheet" href="http://www.example.com/index.v2012.css" type="text/css" media="screen"/>

2.给css文件加个版本号:其实每次修改css文件后还要修改css的文件名有点麻烦,那么我们可以在加载css语句中加入个版本号(即css链接中?后面的内容)就可以了。如原先html中的css调用语句如下:

<link rel="stylesheet" href=“http://www.example.com/style.css?v=2011”type="text/css" media="screen"/>

改一下css文件的版本号改成2012就可以了:

<link rel="stylesheet" href=“http://www.example.com/style.css?v=2012”type="text/css" media="screen"/>

总结

其实css文件后面的问号起不到实际作用,仅能当作后缀,如果用问号加参数的方法,可以添加版本号等信息,同时可以刷新一下浏览器端的缓存。一个小小的细节,可以给我们带来很大的方便。