Determine file size in JavaScript without downloading a file

$0
=
$0
+
$0
No specific Bitcoin Bounty has been announced by author. Still, anyone could send Bitcoin Tips to those who provide a good answer.
0

I have a list of file URLs. For each URL, I need to get the corresponding file size, without downloading the file (it could be a large file). How can I do it in Javascript? Thanks!

1 Answer - total earned - 1.1 mBTC ($0.3 USD)

1
=
2
=
$0.3
2 tips with total amount of 1.1 mBTC($0.3 USD) have been sent by kulibin, Anonimous

The idea is to use HTTP HEAD request and then look at Content-Length response header. HEAD requests always receive just headers and no response body, so no actual data will get downloaded. Here is a sample HEAD request:

javascript file size without downloading http head content length header

.

The concept above is simple, however if you just go ahead and try to implement it, you may encounter the following problems:

Method 1 - Synchronous XMLHttpRequest

If you run this code with Synchronous XMLHttpRequest, Chrome may try to scare you with the following warning message, displayed in the development console:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.

Just ignore that message b/c the end user will never see it. So here is the code:

function getFileSize(url)
{
    var fileSize = '';
    var http = new XMLHttpRequest();
    http.open('HEAD', url, false); // false = Synchronous

    http.send(null); // it will stop here until this http request is complete

    // when we are here, we already have a response, b/c we used Synchronous XHR

    if (http.status === 200) {
        fileSize = http.getResponseHeader('content-length');
        console.log('fileSize = ' + fileSize);
    }

    return fileSize;
}

Method 2 - Asynchronous XMLHttpRequest

Well, for ASYNC XHR we should not be even having that function getFileSize(url) b/c when that function ends, the resulting fileSize is not ready yet :) Welcome to semantics of ASYNC JavaScript. Anyways, love it or hate it, here comes the ASYNC code:

function getFileSize(url)
{
    var fileSize = '';
    var http = new XMLHttpRequest();
    http.open('HEAD', url, true); // true = Asynchronous
    http.onreadystatechange = function() {
        if (this.readyState == this.DONE) {
            if (this.status === 200) {
                fileSize = this.getResponseHeader('content-length');
                console.log('fileSize = ' + fileSize);
                //
                // ok here is the only place in the code where we have our request result and file size ...
                // the problem is that here we are in the middle of anonymous function nested into another function and it does not look pretty
                // this stupid ASYNC pattern makes me hate Javascript even more than I already hate it :)
                //
                //
            }
        }
    };
    http.send(); // it will submit request and jump to the next line immediately, without even waiting for request result b/c we used ASYNC XHR call
    return ('At this moment, we do not even have Request Results b/c we used ASYNC call to follow with stupid JavaScript patterns');
}

Problem - Cross Site Requests

If your Javascript resides in the webpage loaded from mydomain.com, and that script tries to use XMLHttpRequest to get access to some external domain like externalsite.com, any modern browser will stop that request (b/c of the same origin policy) and throw an error message. Here is the error from Chrome:

XMLHttpRequest cannot load http://externalsite.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mydomain.com' is therefore not allowed access.

How to solve that problem? Well, maybe the server that hosts the file you are sizing - maybe that server allows cross domain requests. If not, you could try to use JSONP or some 3rd party function like GM_xmlhttpRequest or a library like xdomain: A library that makes cross-origin requests in all browsers, back to IE8, really easy(I hope so).

DO you have a better solution?

I would appreciate if someone with more JavaScript knowledge than me would provide better solution to Cross Site problem, better explanation and better code examples. Please feel free to post your answers! Thanks!

SEND BITCOIN TIPS

Good answer)

0

Post Answer


Top 3 Tippers
Recent Tips

Will Bitcoin Tipping become a new Internet Culture?


Please share our story! THANK YOU!