WP script versioning breaks cross-site caching?

I am loading JQuery from the google CDN using the following code:

wp_deregister_script('jquery'); 
 wp_register_script(
    'jquery', // handle - WP uses this name to refer to script
    'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',
     array(), // Array of handles representing scripts that this one depends on.
     false, // Version number - defaults to false.
     false // false = put script in header, true = put in footer
 );
wp_enqueue_script('jquery');

In firebug I see that wordpress appends ‘?ver=3.0.4’ to the URL to control caching. In fact there doesn’t seem to be any way to stop WP from appending something to the URL – I can provide my own string in the call to wp_register_script() but WP will use the default ‘ver=3.0.4’ if i leave it blank (or “false”)

Read More

I believe the appended version string stop the user’s browser from re-using a cached copy of the file that it might have downloaded from a different website. E.g.

  1. User visits www.example.com which loads ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js so it is now in browser cache.
  2. User then visits my site which loads ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js?ver=3.0.4
  3. The user’s browser not use it’s cached copy because the URLs are different.

Since cross-site caching is one of the main reasons I want to use Google’s CDN, are there any solutions to this other than loading the script manually (not ideal) or hacking WP core?

TIA

/Eoin/

Related posts

Leave a Reply

6 comments

  1. Use null as $ver param:

    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js', false, null);
    wp_enqueue_script('jquery');
    

    Output:

    <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>
    
  2. I remove version like this, can be easily written out to match multiple domains:

    add_filter( 'script_loader_src', 'jquery_unversion' );
    
    function jquery_unversion( $src ) {
    
        if( strpos( $src, 'ajax.googleapis.com' ) )
            $src = remove_query_arg( 'ver', $src );
    
        return $src;
    }
    
  3. Short answer: No.

    I looked at the code in wp-includes/scriptloader.php and there is nothing that indicates an “option” about supplying the version number.

    You can, however, simply put this in your footer (or header) as an explicit <script> tag. Of course, this completely defeats the whole idea of wp_register_script(), but that’s true with a number of “features” in WP. (Don’t get me started on the brain-dead/broken parsing of shortcodes with regexps.)

  4. Use this in your theme’s functions.php

    function remove_wp_script_version( $src ){
    
        global $wp_version;
    
      $version_str = '?ver='.$wp_version;
      $version_str_offset = strlen( $src ) - strlen( $version_str );
    
      if( substr( $src, $version_str_offset ) == $version_str )
        return substr( $src, 0, $version_str_offset );
      else
        return $src;
    }
    add_filter( 'script_loader_src', 'remove_wp_script_version', 15, 1 ); 
    

    If you want, you can also add another filter to remove versioning from stylesheets.

    add_filter( 'style_loader_src', 'remove_script_version', 15, 1 );
    

    I don’t understand why they put this in the core. Not only does it mess with caching of external scripts but it also gives out unnecessary information about the site. I just use the filters above and add my own version numbers to custom scripts as needed.

  5. Thank you all for your responses. In the end this is the code I used (posting here for the sake of future searchers):

    function control_wp_url_versioning($src)
    {
        // $src is the URL that WP has generated for the script or stlye you added 
        // with wp_enqueue_script() or wp_enqueue_style(). This function currently 
        // removes the version string off *all* scripts. If you need to do something 
        // different, then you should do it here.
        $src = remove_query_arg( 'ver', $src );
        return $src;
    }
    
    // The default script priority is 10. We load these filters with priority 15 to 
    // ensure they are run *after* all the default filters have run. 
    add_filter('script_loader_src', 'control_wp_url_versioning', 15); 
    add_filter('style_loader_src', 'control_wp_url_versioning', 15);