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...
