3

Here is a link to what I mean by magic numbers: file magic

How can I remotely read the first couple bytes (the magic numbers) of a file with JavaScript to determine whether or not it is an image file?

Makoto
  • 104,088
  • 27
  • 192
  • 230
Lev Dubinets
  • 788
  • 10
  • 32

3 Answers3

6

JavaScript is a client-side language in the main, so you can't simply programmatically read files hosted on other sites from your own page. XMLHttpRequest will let you retrieve remote data, but that's going to retrieve the whole file, not the first few bytes. Doing anything more fancy is going to require a server-side helper, e.g. a PHP script or similar.

You should also be aware that some HTTP servers will not allow you to retrieve a range of bytes from the output anyway - they'll always return the whole file. So, even with a PHP script using, say, curl or wget, you may not be able to get this to work for all remote sites:

Is it possible to read only first N bytes from the HTTP server using Linux command?

(The above covers command-line curl, but the conclusions are broadly applicable.)

Edit: Sergiu points out that adding the Range header to an XMLHttpRequest will work, at least for some servers (the Range header is optional for HTTP 1.1). However, cross-domain image retrieval will still need further support such as CORS.

Community
  • 1
  • 1
Dave R.
  • 7,206
  • 3
  • 30
  • 52
  • Well, you can indeed load images from any domain - even without ajax. But you're right, you can only load the full resource as a whole. – Torsten Walter Aug 14 '12 at 23:56
  • Thanks. I understand this from some other readings now, and they designed JS in such a way to rid it of security holes. But it would have been useful. – Lev Dubinets Aug 14 '12 at 23:56
  • 1
    You're referencing the `Same Origin Policy` which is not applicable in this case. However you're correct about the `everything or nothing` part. – Sani Huttunen Aug 15 '12 at 00:00
  • @SaniHuttunen I believe all requests are subject to this, even images. See test fiddle here: http://jsfiddle.net/R6STS/1/ – Dave R. Aug 15 '12 at 01:48
1

There are other similar questions on SO. Like this one.
It might help you to read an image as binary data.

You will need to read the whole image and not just the first few bytes. This is a limitation of JavaScript.

Community
  • 1
  • 1
Sani Huttunen
  • 23,620
  • 6
  • 72
  • 79
1

You could use XMLHttpRequest for this:

  • use the Range request header to specify that you only want a few bytes
  • if the browser supports Cross Origin requests, then you could even request images found on other sites, otherwise you'll have to work with your server only
  • if the browser is new enough, you could even access the response as an ArrayBuffer to access individual bytes as bytes, not as characters

This works for me:

var request = new XMLHttpRequest();
request.open('GET', '/download/logo.png');
request.setRequestHeader('Range', 'bytes=0-5');
request.responseType = 'arraybuffer'
request.addEventListener('load', function() {
  console.log(new Uint8Array(request.response));
});
request.send();
Sergiu Dumitriu
  • 11,455
  • 3
  • 39
  • 62
  • Ok, now this is cool. Although not usable for me as I am writing a commercial application and I need to support old browsers as well as cross domain urls. I will definitely end up using this in some other projects though, thanks! – Lev Dubinets Aug 15 '12 at 00:35