estimate users' upload speed without direct permission [closed] estimate users' upload speed without direct permission [closed] ajax ajax

estimate users' upload speed without direct permission [closed]


Here's an implementation of this using XMLHttpRequest expanding on @Yiğit Yener's idea.

Upload speed is dependent on two things: the user's connection speed and the server's connection speed. I made the assumption here that you want to test the speed between the user and your server. And with XMLHttpRequest, that's really the only option because of the same-origin policy.

With upload speed, you don't need to return anything. You just need to POST a large chunk of data to any page on your server. The easiest page to hit is the one you're already on. To do this you can leave the domain portion of the url out altogether in .open(). POST data is limited on some servers to two megabytes, so I used one to be safe. One is enough to get a decent reading.

To prevent the URL from being cached, I append a random number to the end.

url = '?cache=' + Math.floor( Math.random() * 10000 )

To prevent the POST data from being gzipped, I use random data. The function allows you to pass the number of iterations you wish to check. Iterations are spaced out to every five seconds. The update callback gets called each iteration with the speed of that check, and the moving average of all the checks. Use as many iterations as you wish to get your desired accuracy. If you just want a rough estimate, one iteration is enough.

It's called like this:

checkUploadSpeed( 10, function ( speed, average ) {} );

Demos

You can try this code here.

Private Server

You can try this on ThinkingStiff's own server, which is probably the fastest out of these all.

Stack Snippet

    function checkUploadSpeed( iterations, update ) {        var average = 0,            index = 0,            timer = window.setInterval( check, 5000 ); //check every 5 seconds        check();        function check() {            var xhr = new XMLHttpRequest(),                url = '?cache=' + Math.floor( Math.random() * 10000 ), //random number prevents url caching                data = getRandomString( 1 ), //1 meg POST size handled by all servers                startTime,                speed = 0;            xhr.onreadystatechange = function ( event ) {                if( xhr.readyState == 4 ) {                    speed = Math.round( 1024 / ( ( new Date() - startTime ) / 1000 ) );                    average == 0                         ? average = speed                         : average = Math.round( ( average + speed ) / 2 );                    update( speed, average );                    index++;                    if( index == iterations ) {                        window.clearInterval( timer );                    };                };            };            xhr.open( 'POST', url, true );            startTime = new Date();            xhr.send( data );        };        function getRandomString( sizeInMb ) {            var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+`-=[]\{}|;':,./<>?", //random data prevents gzip effect                iterations = sizeInMb * 1024 * 1024, //get byte count                result = '';            for( var index = 0; index < iterations; index++ ) {                result += chars.charAt( Math.floor( Math.random() * chars.length ) );            };                 return result;        };    };        checkUploadSpeed( 10, function ( speed, average ) {        document.getElementById( 'speed' ).textContent = 'speed: ' + speed + 'kbs';        document.getElementById( 'average' ).textContent = 'average: ' + average + 'kbs';    } );
<div id="speed">speed: 0kbs</div><div id="average">average: 0kbs</div>