可以使用 xhrFields 将 onprogress 功能添加到 jQuery.ajax() 吗?

2022-01-15 00:00:00 xmlhttprequest jquery progress ajax

这里建议:https://gist.github.com/HenrikJoreteg/2502497,我正在尝试将 onprogress 功能添加到我的 jQuery.ajax() 文件上传中.上传工作正常,并且 onprogress 事件正在触发,但不像我预期的那样 - 不是在某个时间间隔重复触发,而是在上传完成时只触发一次.有没有办法指定onprogress刷新的频率?或者,我是否正在尝试做一些无法做到的事情?这是我的代码:

As suggested here: https://gist.github.com/HenrikJoreteg/2502497, I'm trying to add onprogress functionality to my jQuery.ajax() file upload. The upload works fine, and the onprogress event is firing, but not as I expected--instead of firing repeatedly at some time interval, it's firing only once, when the upload has completed. Is there a way to specify the frequency of onprogress refreshes? Or, am I trying to do something that can't be done? Here's my code:

    $.ajax(
    {
        async: true,
        contentType: file.type,
        data: file,
        dataType: 'xml',
        processData: false,
        success: function(xml)
        {
            // Do stuff with the returned xml
        },
        type: 'post',
        url: '/fileuploader/' + file.name,
        xhrFields:
        {
            onprogress: function(progress)
            {
                var percentage = Math.floor((progress.total / progress.totalSize) * 100);
                console.log('progress', percentage);
                if (percentage === 100)
                {
                    console.log('DONE!');
                }
            }
        }
    });


嗯,已经好几年了.我重新审视了这一点,并使用 GetFree 的答案,将我的代码更新为以下内容:


Well, it's been a few years. I revisited this, and using GetFree's answer, I updated my code to the following:

$('#file_input').change(function()
{
    var file = this.files[0];
    $('#upload_button').click(funtion(e)
    {
        req = new XMLHttpRequest();
        req.upload.addEventListener('progress', updateProgress, false);
        req.addEventListener('load', transferComplete, false);
        var url  = 'https://my.url'; 
        req.open('POST', url, true);
        req.setRequestHeader('Content-Type', myFileType);
        req.setRequestHeader('Content-Length', myFileLength);
        req.send(file);
    });
);
function updateProgress(e)
{
    var percent = Math.floor(e.loaded / e.total * 100);
    console.log("percent = " + percent);
}
function transferComplete(e)
{
    console.log("transfer complete");
}

我已将 GetFree 的帖子标记为已接受的答案.抱歉耽搁了.

I have marked GetFree's post as the accepted answer. Sorry for the delay.

推荐答案

简答:
不,你不能使用 xhrFields 做你想做的事.

长答案:

XmlHttpRequest 对象中有两个进度事件:

There are two progress events in a XmlHttpRequest object:

  • 响应进度(XmlHttpRequest.onprogress)
    这是浏览器从服务器下载数据的时候.

  • The response progress (XmlHttpRequest.onprogress)
    This is when the browser is downloading the data from the server.

请求进度 (XmlHttpRequest.upload.onprogress)
这是浏览器向服务器发送数据(包括 POST 参数、cookie 和文件)的时候

The request progress (XmlHttpRequest.upload.onprogress)
This is when the browser is sending the data to the server (including POST parameters, cookies, and files)

在您的代码中,您使用的是响应进度事件,但您需要的是请求进度事件.这就是你的做法:

In your code you are using the response progress event, but what you need is the request progress event. This is how you do it:

$.ajax({
    async: true,
    contentType: file.type,
    data: file,
    dataType: 'xml',
    processData: false,
    success: function(xml){
        // Do stuff with the returned xml
    },
    type: 'post',
    url: '/fileuploader/' + file.name,
    xhr: function(){
        // get the native XmlHttpRequest object
        var xhr = $.ajaxSettings.xhr() ;
        // set the onprogress event handler
        xhr.upload.onprogress = function(evt){ console.log('progress', evt.loaded/evt.total*100) } ;
        // set the onload event handler
        xhr.upload.onload = function(){ console.log('DONE!') } ;
        // return the customized object
        return xhr ;
    }
});

xhr 选项参数必须是返回原生 XmlHttpRequest 对象以供 jQuery 使用的函数.

The xhr option parameter must be a function that returns a native XmlHttpRequest object for jQuery to use.

相关文章