Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript img.src onerror event - get reason of error

Tags:

javascript

There can be different reasons for <img> load errors, such as network error response, bad image data...

error object received from onerror doesn't seems to specify the exact reason.

Is there a way to know if the error is because of a network error, say HTTP 500 or a network timeout?

EDIT: I'm not looking for an alternative way to load a resource, such as AJAX request. I need an answer specifically for <img> tag with onerror event. The reason for that is that I'm using this method for pixel-tracking and I need a way to retry on upon network errors. I'm also not looking for alternative tracking methods such as JSONP.

like image 504
Max Avatar asked Nov 13 '16 10:11

Max


People also ask

What is Onerror in IMG tag?

Definition and Usage The onerror event is triggered if an error occurs while loading an external file (e.g. a document or an image). Tip: When used on audio/video media, related events that occurs when there is some kind of disturbance to the media loading process, are: onabort.

Is Onerror deprecated?

A "deprecated attribute" warning is shown when using React's onError attribute on a <img> element. But the onError props is valid in React (see the documentation). However, the HTML onerror attribute is indeed deprecated (see on MDN), but it should not be triggered in JSX code.

What is the use of JavaScript Onerror event?

What is onerror() Method in JavaScript? The onerror event handler was the first feature to facilitate error handling in JavaScript. The error event is fired on the window object whenever an exception occurs on the page.

What are the three information provided by Onerror () method?

The Error object and error. It contains 3 standardized properties: message, fileName, and lineNumber. Redundant values that already provided to you via window. onerror .


Video Answer


1 Answers

Edit 16Nov16 2020GMT

Maybe you are pixel-tracking in emails or other clients limited in Javascript capabilities.

One idea that comes to mind is to use URL query paramters in your <img>'s src URL.

With regards to network timeouts, I will pose the idea that a user opens an email, loads the email entirely, then disconnects from the internet and somehow this does not give the tracker enough time to load.

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout

I would suggest to use setTimeout() inside your onerror function. This will continue attempting to set/load the <img>'s src URL. You could append the seconds it took until successful load to the URL of your src file as a query parameter like ?s=<sec>

As far as determining status 500 codes on image loads you might want to consider creating a custom 500 error file which would then create -- for example -- a MySQL database entry with all sorts of information you have access to and if you chose to use the query parameters mentioned before then you have slightly more information added to the error.

onerror for <img> gives limited information about the network

The information that is available from <img> can be found at https://www.w3.org/TR/html/semantics-embedded-content.html#htmlimageelement-htmlimageelement

error event img src


Older answer:

Perhaps a route you would like to try is to use AJAX to load the image data and set the <img> src to the base64 of the image data received. I hope this helps.

Edit 14Nov16 2018GMT

Alternatively use AJAX to determine if the image loads properly and then use the same URL sent to AJAX as the src for your <img>. It would of course be redundant but would avoid the issue of long "data" URLs.

Edit 15Nov16 0832GMT

Also regarding Network Timeout I found this thread to be useful JQuery Ajax - How to Detect Network Connection error when making Ajax call Apparently you can specify a timeout to AJAX much like using error except you just provide the miliseconds manually.

Converting to Base64

https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding

  • https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/btoa

      var encodedData = window.btoa("Hello, world"); // encode a string
    

Or if you are concerened about older browsers able to use btoa() then you might be interested in Google's https://chromium.googlesource.com/chromiumos/platform/spigots/+/refs/heads/firmware-u-boot-v1/base64_encode.js

Status Code checks in jQuery's AJAX

jQuery: How to get the HTTP status code from within the $.ajax.error method?

$.ajax({
    type: 'GET',
    url: '/path-to-my/image.png',
    data: null,
    success: function(data){
        alert('horray! 200 status code!');
        // convert to base64; add to img.src # btoa(data)
        document.querySelector("#hlogo img").src = "data:;base64,"+ data;
    },
    error:function (xhr, ajaxOptions, thrownError){
        switch (xhr.status) {
            case 400:
                 // Take action, referencing xhr.responseText as needed.

            case 404:
                 // Take action, referencing xhr.responseText as needed.

            case 500:
                 // Take action, referencing xhr.responseText as needed.
        }
});

Notes

  • https://www.rfc-editor.org/rfc/rfc2397#section-3

      dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data
      mediatype  := [ type "/" subtype ] *( ";" parameter )
      data       := *urlchar
      parameter  := attribute "=" value
    
  • https://www.rfc-editor.org/rfc/rfc2046#section-4.2

Using of a generic-purpose image viewing application this way inherits the security problems of the most dangerous type supported by the application.

  • https://www.rfc-editor.org/rfc/rfc2397#page-4

The effect of using long "data" URLs in applications is currently unknown; some software packages may exhibit unreasonable behavior when confronted with data that exceeds its allocated buffer size.

Other References

  • Unknown file type MIME?
  • Asynchronously load images with jQuery
like image 65
ŽaMan Avatar answered Oct 07 '22 07:10

ŽaMan