The most reliable and compatible way to check if the source point is a valid image is to use the Image
object. If it can load it as an image onload
will trigger, if not onerror
will trigger:
var img = new Image;
img.onload = function() { /* OK */ };
img.onerror = function() { /* cannot read this as an image */ };
img.onabort = function() { /* connection or source was reset */ };
img.src = "URLtoCheckHere";
The drawback is of course that the whole image would be loaded before you could find out if the browser can read and decode it.
If Image
for some reason can't be used you could read the source point via XHR but that comes with its own restrictions, one being cross-origin resource sharing. If the image is not of the same origin (protocol, domain, port etc.) and the external server does not allow cors-usage, reading would simply fail.
However, if these limitations aren't a problem (i.e. the images comes from the same server as the page or a cors-friendly site) then you could read in part of the image as ArrayBuffer
and check the magic numbers for the image types you want to support. Be aware of byte-order.
To specify a range use the Range
header (it's not sure the server will respect it though).
Assuming the part of the file has been read into an ArrayBuffer
:
var reader = new DataView(arrBuffer);
if (reader.getUint32(0) === 0x89504E47 &&
reader.getUint32(4) === 0x0D0A1A0A) {
// this seem to be a PNG file
}
else ... etc.
But, even if the file is detected as a valid image file, there is no guarantee of that the file is not corrupt and so forth. There is no way to validate the file using this method (unless you chose to write a parser yourselves).
So in conclusion, Image
is the best option in most scenarios. It has been through several iterations over the years in the main browsers and is pretty robust and stable.