• Changing an Image src in Opera

    A slide projector and two landscape slides on a desk, with a blue mountain image projected onto the wall.

    What could be simpler than changing an image on a page with JavaScript? It was 2012; cross-browser libraries like jQuery had long been in use, accounting for every tiny whim of every engine. What problems could possibly appear? As it turned out, all sorts. The obvious attempt to refresh the CAPTCHA by assigning the same img src did exactly nothing.

    js
    $('#kcaptcha').attr('src', '../includes/captcha/run.php');

    Apparently, the browser believed that changing meant replacing one thing with another, and that writing the same thing twice made no sense. There is some logic in that, of course, but perhaps programs should not argue with programmers. Fine, I then tried adding some changing part to the path, one that would not affect the image output from the script but would force the browser to refresh it.

    js
    $('#kcaptcha').attr('src', '../includes/captcha/run.php#' + Math.random());

    The other browsers I tried fell for that trick: they reloaded the poor image. But the Norwegian beauty persisted in her unwillingness to compromise.

    Opera’s behavior was consistent with URL semantics: the fragment is removed before the resource is retrieved. Changing #… does not change the HTTP request target, so it is not a reliable way to bypass the HTTP cache. That observation alone was no evidence of an Opera bug. I moved the random number into the query string instead:

    js
    $('#kcaptcha').attr('src', '../includes/captcha/run.php?junk=' + Math.random());

    At this point Opera softened and obediently started changing the image.

    The query string changes the request’s target URI, which is part of the HTTP cache key. This cache-busting technique still applies today; it was not specific to Opera. It changes the URL used to retrieve the image, but the server still determines whether the returned image is actually different.