How to get HTTP status code of <img> tags

15,229

Solution 1

No, there is no way to get the HTTP status from a request made by an img tag in JavaScript.

You could write a firefox plugin, chrome/safari extension to do that.

An alternative would be using AJAX to load your images (not using img tags). You can get Http Status Codes from Ajax Requests.

Solution 2

You cannot check HTTP status this way. However you can check if image was loaded or not using naturalWidth property.

if (img.naturalWidth === 0) {
    // do sth
}

Hope it help.

Solution 3

You may combine the couple technics to get img.status:

<img src="/no.img" onerror="error(this)">

function error(img) {
   var r = makeXMLHttpRequestAgain(img.src);
   if (r.status === 500) img.src = '/e500.img';
   if (r.status === 503) img.src = '/e503.img';
}

Solution 4

 function loadBinaryImageAndInsertToImgTag(imgElement, imageUrl) {
        let xhr = getXMLHttpRequest();
        xhr.onreadystatechange = ProcessResponse;
        xhr.open("GET", imageUrl, true);
        xhr.overrideMimeType('text/plain; charset=x-user-defined');
        xhr.send(null);

        function getXMLHttpRequest() {
            let xhr = null;

            if (window.XMLHttpRequest || window.ActiveXObject) {
                if (window.ActiveXObject) {
                    try {
                        xhr = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        xhr = new ActiveXObject("Microsoft.XMLHTTP");
                    }
                } else {
                    xhr = new XMLHttpRequest();
                }
            } else {
                alert("Your browser does not support XMLHTTP");
                return null;
            }
            return xhr;
        }

        function ProcessResponse() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    imgElement.src = "data:image/jpeg;base64," + encode64(xhr.responseText);
                    imgElement.style.display = "";
                } else {
                    alert("Error retrieving data!");
                }
            }
        }

        function encode64(inputStr) {
            let b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
            let outputStr = "";
            let i = 0;

            while (i < inputStr.length) {
                let byte1 = inputStr.charCodeAt(i++) & 0xff;
                let byte2 = inputStr.charCodeAt(i++) & 0xff;
                let byte3 = inputStr.charCodeAt(i++) & 0xff;
                let enc1 = byte1 >> 2;
                let enc2 = ((byte1 & 3) << 4) | (byte2 >> 4);
                let enc3, enc4;
                if (isNaN(byte2)) {
                    enc3 = enc4 = 64;
                }
                else {
                    enc3 = ((byte2 & 15) << 2) | (byte3 >> 6);
                    if (isNaN(byte3)) {
                        enc4 = 64;
                    }
                    else {
                        enc4 = byte3 & 63;
                    }
                }
                outputStr += b64.charAt(enc1) + b64.charAt(enc2) + b64.charAt(enc3) + b64.charAt(enc4);
            }
            return outputStr;
        }
    }
Share:
15,229
Artem Pyanykh
Author by

Artem Pyanykh

Updated on July 23, 2022

Comments

  • Artem Pyanykh
    Artem Pyanykh over 1 year

    I have a page with a lot of images that are generated server-side depending on user actions. And when image loads successfully I'm happy, but when there is an error on the server I have to act according to what an error occurred.

    For example:

    • 500 code: do this stuff.
    • 503 code: do that stuff

    and so on.

    So, my question: is there any way to get status code within "img" tag on-error event handler?

  • Sikshya Maharjan
    Sikshya Maharjan over 12 years
    Please note that, from the API for .error(): "The event handler must be attached before the browser fires the error event, which is why the example sets the src attribute after attaching the handler." (emphases mine).
  • Raynos
    Raynos over 12 years
    just throw some jQuery at it, surely it will solve the problem!
  • Artem Pyanykh
    Artem Pyanykh over 12 years
    Plugin is not acceptable. AJAX seems to be fine, but what kind of data should I get through AJAX? I can retrieve the image data, but I can't use it to create img element.
  • Matt Greer
    Matt Greer over 12 years
    You would most likely need to send it as a data url. You'll probably need to find some kind of library that can generate data urls on the server side. Then once they arrive it's just a matter of setting the img's src to the data url. This will add a good deal of overhead to loading your images. The real solution is probably to fix the server so it always successfully sends images.
  • Axle
    Axle about 11 years
    For anyone reading this page, the naturalWidth property is not supported by all browsers. This property is also quite touchy - you should only attempt to read it after the image has loaded. (stackoverflow.com/questions/1645166/…) I hope that helps. :)
  • Wojciech Bednarski
    Wojciech Bednarski about 11 years
    @Axle You are referring to the post from '09. Now it works in all latest browsers version.
  • Axle
    Axle about 11 years
    I happen to work somewhere that makes it a requirement to support older browsers (IE 7 and IE 8 for example). I'm sure there are others out there that suffer a similar fate. Trust me, screaming "Well they should just update their broken tools!" never got me anywhere. :P
  • Wojciech Bednarski
    Wojciech Bednarski about 11 years
    @Axle Well, there is no IE7 or 8 since upgrade to IE9 is forced. If somebody has older version its mean it is pirate Windows version :- ) Anyway I (and company I'm working for) don't care about anything that is not latest. In fact I only test stuff in Google Chrome, when works is fine.
  • Axle
    Axle about 11 years
    That's nice. This discussion, however, is quite pointless. Fact of the matter is, there are people out there that do use the older browsers (government included), and some of us have to support it. My initial comment was not an attack on you - it was meant for the other poor saps, like myself, forced to support legacy browsers. And that's all I have to say about that.
  • Axle
    Axle about 11 years
    (Looks like I missed the grace period to append this to the above comment) I'd also like to add: Can I work where you are?
  • Andy E
    Andy E almost 11 years
    @Axie, Wojciech, img.complete is what you should look at to see if an image is loaded or not, or for guaranteed compatibility you could attach to the onload event.
  • Tarun
    Tarun about 9 years
    As per Microsoft support policy it looks like they would support it till 12 January 2016. So as a developer we should also make sure that our web pages works in it till then.
  • Fusion
    Fusion almost 8 years
    Ajax is not a good substitution in case, your wanna-load-images are placed on external domain. Anything new about this issue in 2016?
  • Tino
    Tino over 2 years
    Why encode64 instead of btoa?
  • Tino
    Tino over 2 years
    Source of makeXMLHttpRequestAgain?
  • iEfimoff
    iEfimoff over 2 years
    @Tino, makeXMLHttpRequestAgain is not implemented yet. The idea is to make XMLHttpRequest to get the status code.
  • Tino
    Tino over 2 years
    My problem is, <img> is loaded with status code 200 (usually, except a few cases) while XMLHttpRequest returns 402 due to how XMLHttpRequest or fetch work. The web page is under my control while the <img>-site isn't. The <img> site protects against linking images from unauthorized sites. My site is authorized. .decode() does not work either, as .decode() often fails while the <img> looks ok. .naturalWidth works but gives no hint why or how the <img> failed, i.E. if it is 402, 404, 408 or 500 etc. AFAICS only a browser extension can fix this ..
  • iEfimoff
    iEfimoff over 2 years
    In your case a free generate ssl certificate solves your problem.
  • Tino
    Tino over 2 years
    Throwing additional SSL onto this does not help as it is already present. The <img>-site (which is NOT under my control) is like https://images.example.net/image.jpg while my website (which IS under my control) is like https://www.example.org/img.html