Bandit Design » Our Design Our Portfolio Contact Us
Tutorials TumbleLog Our Thoughts
Quite often at Bandit Design while we're working on your project, we'll stumble upon interesting or humourous things -- so we thought why not share them with the world!
RSS iPhone Random Archive « Home

Bandit Design

This is a TumbleLog authored at the desks of Bandit Design. We're a small web and graphic design studio based in Wellington, New Zealand.

Visit Bandit Design »

3 years ago

Version checking a Greasemonkey Script without AJAX

Lately I’ve been updating my Lighthouse++ script quite frequently. Every time I push a new version out, I have to attempt to notify everybody and post on my blog/twitter - this is a pain and some people are missing out on new or important features.

I looked into how to do some cross-site AJAX requests to check for a new version, but it really isn’t possible with a Greasemonkey script in Chrome, due to how Chrome manages its sandbox.

I tested a LOT of third party Javascript libraries that claimed to bypass any and all issues (with James Padolsey’s solution looking amazing) — but no dice, no matter what I tried.

I came up with an ingenious plan to use a PHP proxy hosted on my server, but access it via an image — if the image “loaded” then the script version was current — if not (a sneaky 404), it was out of date.

The script works like a charm, you can try the raw version here; anything other than (at the time of writing) 0.61 will cause a 404 error, which is then passed on to my script, and a NEW VERSION AVAILABLE message is displayed.

Below is the source code for my script — it simply references a 1x1 transparent PNG image, and a blank .txt file — very easy for anybody to set up (although note it will only work if your versions are numbers):


<?php
	// version files
	$file = 'version.txt';
	$image = 'version.png';
	$script = 'http://userscripts.org/scripts/show/81657';
	
	// check last modified date of version.txt, only do the version check every 6 hours max
	if($_GET['force'] || (time() - filemtime($file)) >= 21600) {
		
		// get contents of userscripts page
		$html = trim(strip_tags(file_get_contents($script)));
		
		// extract the version
		preg_match('|Version:\s+([0-9\.]+)\s*|', $html, $result);
		$version = trim($result[1]);
		
		// update version.txt
		$fo = fopen($file, 'w+');
		fwrite($fo, $version);
		fclose($fo);
		
	}
	
	// grab the version from the version file if we don't already have it
	if(!$version) $version = trim(file_get_contents($file));
	
	// compare it to the version we were provided
	if($version == $_GET['version']) {
		
		// same version, output a picture
		header('Content-Type: image/png', true);
		header('Content-Transfer-Encoding: binary');
		header('Content-Length: '.filesize($image), true);
		header("Cache-Control: no-cache, must-revalidate");
		header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
		
		readfile($image);
		exit;
		
	}
	else {
		
		// different version, 404
		header('HTTP/1.1 404 Not Found');
		exit;
		
	}
?>

With a super basic .htaccess file (but you don’t need this):


Options +FollowSymlinks
RewriteEngine On

RewriteRule version.png version.php [NC,QSA,L]

And the Javascript (jQuery) code looks something like this:


$("<img />").appendTo("body").bind("load", function() {
	// version up-to-date, everything is fine
	$(this).hide();
}).bind("error", function() {
	// version out of date!
	$("#lpp-advert").append(" — NEW VERSION AVAILABLE!");
	$(this).hide();
}).attr("src", "https://lab.bandit.co.nz/scripts/lighthouseplusplus/version.png?version=" + version);

You can try it, and my script out at http://userscripts.org/scripts/show/81657

Loading...