未经直接许可估算用户的上传速度

时间:2013-03-18 08:14:30

标签: javascript ajax html5 performance file-upload

我希望粗略估计用户的上传速度,而无需获得直接许可。这只是为了区分真正慢的连接和非常快的连接,所以准确性并不是非常重要......

3 个答案:

答案 0 :(得分:12)

以下是使用XMLHttpRequest扩展@Yiğit Yener's想法的实现。

上传速度取决于两件事:用户的连接速度和服务器的连接速度。我在此假设您要测试用户与您的服务器之间的速度。使用XMLHttpRequest,由于same-origin policy,这确实是唯一的选择。

使用上传速度,您无需返回任何内容。您只需要将POST大量数据发送到服务器上的任何页面即可。最容易点击的页面是您已经使用的页面。为此,您可以在.open()中完全保留网址的域部分。某些服务器上的POST数据限制为2兆字节,因此我使用了一个安全数据库。一个就足以得到一个体面的阅读。

为了防止缓存URL,我在末尾附加一个随机数。

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

为防止POST数据被gzip压缩,我使用随机数据。该函数允许您传递要检查的迭代次数。迭代间隔为每五秒钟。每次迭代都会调用update回调,并以该检查的速度和所有检查的移动平均值进行调用。使用尽可能多的迭代来获得所需的精度。如果您只是想要粗略估计,那么一次迭代就足够了。

它被称为:

checkUploadSpeed( 10, function ( speed, average ) {

} );

演示

您可以在此处尝试此代码。

专用服务器

你可以在ThinkingStiff's own server上试试这个,这可能是这些中最快的。

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>

的jsfiddle

托管演示的JSFiddle服务器速度较慢。

点击此按钮转到小提琴:

JSFiddle

答案 1 :(得分:2)

您可以向发送/返回大量数据的服务发出异步ajax请求,并测量客户端加载所需的时间。这当然受到客户当前网络使用的影响。

答案 2 :(得分:1)

想到这一点的一种方法是创建一个iframe,其中form中包含textarea,请填充textarea大量的iframe随机字符,然后以编程方式提交表单。让提交响应调用父窗口说出它何时完成,并测量从提交到完成的时间。您可能从一个相对较小的有效负载开始(因此它不会永远在缓慢的连接上),如果它很快返回,重复越来越大的有效负载,直到您对结果满意为止。使用ajax可以完成同样的事情,我想,不确定为什么我会立即考虑{{1}}。请参阅Stack Overflow上的my other answer,但请考虑越来越大的表单数据而不是下载数据。

这将为您提供非常粗略的上传速度指标。