11

Generalities

I'd like to append a random string to an element's attribute, using either jQuery or javascript.

Specifics

I need to reference a CSS file that lives on a CDN. Unfortunately, the CDN changes the URL of this CSS file every time the file is updated. So I can't simply refer to a static URL.

It turns out tho, that if you append a string to the end of the URL that the CDN has never seen before, it will return the most recent version of the file. Bogus to be sure.

e.g.

<link href="http://example.com/style.css?randomString-neverSeenBefore">

I know, this is ugly, faulty and insane. But sometimes that's how the cookie crumbles. The alternative would be to attempt to maintain, in parity, a growing battery of CSS files and template headers... not viable. ;)

What I've got so far,

My jQuery skills are meager. I've found two different bits of code that do what I need on their own but I can't for the life of my figure out how to get them to work together.

bit of code #1:

        // this guy is a random number generator that i found
        jQuery.extend({
        random: function(X) {
            return Math.floor(X * (Math.random() % 1));
        },
        randomBetween: function(MinV, MaxV) {
          return MinV + jQuery.random(MaxV - MinV + 1);
        }
    });


    // using above plugin, creates 20 random numbers between 10 and 99
    // and then appends that 40 digit number to a paragraph element
    for (i = 0; i < 20; i++) {
        $('p').text(    
            $('p').text() + ($.randomBetween(10, 99) )
            );
    }

bit of code #2:

    // this fellow creates a link to the style sheet
    // after the page has loaded
    var link = $("<link>");
    link.attr({
            type: 'text/css',
            rel: 'stylesheet',
            href: 'http://example.com/style.css'
    });
    $("head").append( link ); 

I assume "bit of code #2" is required: my presumption is that were I to simply appended a random number to the end of an existing "href" attribute, nothing would happen. i.e. the CSS file would not be reloaded.

Thanks a million for your help on this! :)

Jon

jon
  • 5,961
  • 8
  • 35
  • 43

3 Answers3

28

Adding a random string is called a cache-buster. You shouldn't do it on every page load as it completely defeats the purpose of cache.

To answer how to accomplish it with a random string, you can try this:

$('<link/>').attr({
                   type: 'text/css',
                   rel: 'stylesheet',
                   href: 'http://example.com/style.css?' + randString(4)
}).appendTo('head');

Here's a simple random string generator function:

/**
 * Function generates a random string for use in unique IDs, etc
 *
 * @param <int> n - The length of the string
 */
function randString(n)
{
    if(!n)
    {
        n = 5;
    }

    var text = '';
    var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    for(var i=0; i < n; i++)
    {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    return text;
}
AlienWebguy
  • 76,997
  • 17
  • 122
  • 145
16

Keep it simple, apply the current timestamp in miliseconds to the URL:

// this fellow creates a link to the style sheet
// after the page has loaded
var link = $("<link>");
link.attr({
        type: 'text/css',
        rel: 'stylesheet',
        href: 'http://example.com/style.css?' + (new Date).getTime()
});
$("head").append( link );

Please note that this is really a bad idea, if you're not going to change your stylesheet much, just replace the URL manually in the files. There are tools for that purpose available (sed under Linux-based systems)

Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
  • 1
    yea. i hear you that it's a bad idea. unfortunately my hands are tied as i'm using a hosted service (offering little control) and dozens of landing pages (hence dozens of places to change the CSS each time a change is made). it's either a hack, or tweaking and improving less. time won't allow for both... sometimes you've got to make a bad decision to make another better one ;) --- thanks for this, it's a stroke of brilliance. :) – jon Aug 06 '11 at 16:51
2

You can get just part of the date, for example:

var d = new Date;

// this string will change once a day for the same user
var rnd_str_day = d.getFullYear() + '_' + d.getMonth() + '_' + d.getDay();
href= 'http://example.com/style.css?' + rnd_str_day;

// this string will change once an hour
var rnd_str_hour = d.getFullYear() + '_' + d.getMonth() + '_' + d.getDay() + '_' + d.getHours();
href= 'http://example.com/style.css?' + rnd_str_hour;

And so the css will be uncached once a day or an hour, depending on your requeriments.

Fernando
  • 1,013
  • 2
  • 10
  • 23