Client side 404 error detection for images

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Client side 404 error detection for images

Post by Benjamin »

I need to build a solution that will detect when images receive a 404 error response. Even if an image does load, the HTTP response code may still be a 404 Not Found. After the page has completely loaded, I need to gather an array of all paths to images that returned a 404 response code and submit them back to my server via ajax.

Any clues how this can be done?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Client side 404 error detection for images

Post by Weirdan »

something like this could work if put into document head:

Code: Select all

// experiment with this at http://jsfiddle.net/9ttmJ/
var images = document.get​ElementsByTagName('img')​​​​;
var failedImages = [];
for (var i = 0, l = images.length; i < l; i++) {
    images[i].onerror = function() {
        failedImages.push(this);     
    }​;
}
$(window).load(function() {
    console.log(failedImages);
});
​
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Client side 404 error detection for images

Post by Benjamin »

Yeah I saw a similar solution while searching. I tested that, but onerror is null because an image is being returned. Even though an image exists, what I need to detect is the actual 404 Not Found header.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Client side 404 error detection for images

Post by Weirdan »

Another alternative that I could think of would be not really checking if an image is loaded, but do a second request (probably HEAD) to the src url, assuming it's unlikely that image was added or removed inbetween two requests. If image is cached by the browser unconditionally it might be even better to do full GET request and expect browser to serve it from cache with all the headers you need.
Even though an image exists, what I need to detect is the actual 404 Not Found header.
Do you have public examples of such urls I could use for testing?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Client side 404 error detection for images

Post by Weirdan »

Seems to be working, but can't work cross-domain

Code: Select all

// http://jsfiddle.net/SRvqN/1/
$(window).load(function() {
    $('img').each(function() {
        var url = $(this).attr("src");
        $.ajax(url, {
            cache: true,
            statusCode: {
                404 : function() {
                    $('table').append('<tr><td>' + url + '</td></tr>');
                }
            }
        });
    });
});
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Client side 404 error detection for images

Post by Benjamin »

I was just going to mention that I was going to try ajax but figured it wouldn't work across domains. These images will also be lazy loaded so I thought why not lazy load them via ajax and test them at the same time. I'm not sure this is possible.

Here's code that will generate something very close to what is being sent.

Code: Select all

<?php
header("Status: HTTP/1.1 404 Not Found");
header("Date: Fri, 13 Jul 2012 17:42:27 GMT"); # current timestamp
header("Expires: Fri, 13 Jul 2012 17:42:57 GMT");
header("Cache-Control: public, max-age=30");
header('Content-Length: 168');
header('Content-Type: image/png');
header("Connection: close");

$image = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAAlwS'
        .'FlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wHEwswBfrdfwgAAAAidEVYdENvbW1lbnQAQ3'
        .'JlYXRlZCB3aXRoIEdJTVAgb24gYSBNYWOHqHdDAAAADElEQVQI12P4//8/AAX+Av7czFn'
        .'nAAAAAElFTkSuQmCC';

echo base64_decode($image);
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Client side 404 error detection for images

Post by Weirdan »

Lazy load them via ajax and test them at the same time. I'm not sure this is possible.
It's possible, but I'm not sure it's 100% cross-browser. For IE you would have to add JS implementation of btoa() (Base64 encoder):

Code: Select all

<html>
<head>
    <script src="jQuery/jquery.js"></script>
    <script>
        $(function() {
            $('img').each(function() {
                var elt = $(this);
                var url = elt.attr('data-src');
                $.ajax(url, {
                    cache: true,
                    beforeSend: function(jqXHR) {
                        jqXHR.overrideMimeType("text/plain; charset=x-user-defined");
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        $('body').append("<br>failed to load:" + url);
                    },
                    success: function(data, textStatus, jqXHR) {
                        console.log(data.length);
                        var d = "";
                        for (var i = 0, l = data.length; i < l; i++) {
                            d += String.fromCharCode(data.charCodeAt(i) & 0xff);
                        }
                        elt.attr("src", "data:image/png;base64," + btoa(d));
                    }
                });
            });
        });
    </script>
</head>
<body>                                                                                                                                  
<img data-src="img.php"/>                                                                                                               
<img data-src="exists.jpg"/>                                                                                                            
</body>                                                                                                                                 
</html>                         
The trick is to override mime type so browser would think it's 8bit and post-process received data stripping everything but lowest byte.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Client side 404 error detection for images

Post by Benjamin »

Thank you. It doesn't have to work in all browsers. I will run some tests on this.
Post Reply