简体   繁体   English

XHR2进度回退

[英]XHR2 Progress Fallback

I have the following example which uses the progress events in XHR2 to display a progress bar to the user when performing an AJAX request: 我有以下示例,该示例在执行AJAX请求时使用XHR2中的进度事件向用户显示进度栏:

$.ajax({
    xhr: function() {

        var xhr = new window.XMLHttpRequest();

        xhr.upload.addEventListener('progress', function(evt){

            if (evt.lengthComputable) {

                var percentComplete = (evt.loaded / evt.total) * 100;

                if(percentComplete >= 100){
                    $('#loading-bar').find('.bar').css({'width': percentComplete + '%'});
                    $('#loading-bar')
                    .find('.bar')
                    .on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() {
                        $('#loading-bar').fadeOut(function(){
                            $('#loading-bar').find('.bar').css({'width': ''});
                        });
                    });
                } else {
                    $('#loading-bar').find('.bar').css({'width': percentComplete + '%'});
                }
            }                               

        }, false);

        return xhr;

    },
    type: 'GET',
    url: 'Test.html',
    success: function (response) {


    },
    error: function (jqXHR, textStatus, errorThrown) {


    }
});

However for browsers that don't support XHR2, the bar won't animate nor will the loading-bar element be faded out from the DOM. 但是,对于不支持XHR2的浏览器,该栏将不会设置动画,并且loading-bar元素也不会从DOM中淡出。

How can I implement a fallback? 如何实施后备广告? As I don't want to just fade the loading bar out on success as that will then conflict with the progress events for browsers that DO support it. 因为我不想只是淡出成功的加载栏,否则将与确实支持它的浏览器的进度事件发生冲突。

Or even better is it possible to get the progress by alternate means? 甚至更好的办法是通过其他方式获得进展?

If it's download progress, we can do it when xhr.readyState >= 3 . 如果下载进度良好,则可以在xhr.readyState >= 3 Just read the xhr.responseText.length , and then divide it by parseInt(xhr.getResponseHeader('Content-Length')) (assuming the server provides this header and it's same origin or with correct CORS header). 只需读取xhr.responseText.length ,然后将其除以parseInt(xhr.getResponseHeader('Content-Length')) (假设服务器提供了此标头,并且该标头具有相同的来源或具有正确的CORS标头)。

If it's upload progress, I don't know any method to polyfill it purely within the client-side. 如果是上传进度,我不知道有什么方法可以完全在客户端内部进行填充。 We can create an id for every upload session, and use another xhr to pull the upload receiving progress from the server. 我们可以为每个上传会话创建一个ID,并使用另一个xhr来从服务器获取上传进度。 However that requires complicated implementation on the server-side. 但是,这需要在服务器端进行复杂的实现。 There are many such implementations in common languages, for example for PHP or .NET. 有许多这样的通用语言实现,例如PHP或.NET。 You can look into them and implement your own. 您可以研究它们并实现自己的。

Try using .onreadystatechange() with .readyState : 尝试将.onreadystatechange().readyState一起.readyState

getter.onreadystatechange = function() {
    if (loading) { //If the loading element has been loaded...
        if (this.status === 200) { //If this.status is already 200...
            loading.style.width = this.readyState*25+"%"; //This sets the width of loading according to this.readyState
            if (this.readyState === 4) {
                //We hide loadingBar and do stuff when we're done.
                loadingBar.style.display = "none";
               [do stuff]
            }
        }
    }
};

If you're accepting 100 Continue statuses, you might also want to account for that into your loading bar. 如果您接受100 Continue状态,则可能还需要在加载栏中说明。 The way this is now, it's at a standstill for a while, but then zooms to 100% when it gets to the status 200 OK and the readyState property goes from 2 to 4 . 现在,它处于停顿状态,但是当状态变为200 OK并且readyState属性从2变为4时,缩放到100%。

Here's the fiddle: http://jsfiddle.net/NobleMushtak/QRuU6/ 这是小提琴: http : //jsfiddle.net/NobleMushtak/QRuU6/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM