跟踪基本HTML表单发布进度

Track basic HTML form post progress

本文关键字:布进度 表单 HTML 跟踪      更新时间:2023-09-26

我有一个基本的HTML表单,它可以正常提交,根本没有ajax。此表单使用常规邮件提交到同一文件中。我不使用AJAX,因为表单有12个文本字段和至少1个图像,但可能最多有26个图像,而且AJAX不能同时处理表单和图像,我必须保存到数据库中,这比AJAX需要做很多额外的工作。

问题是我需要以某种方式跟踪表单上传进度。大多数程序员都知道在浏览器的左下角或右下角查看表单提交进度。但大多数人并不知道这一点。

所以我想显示一个进度条。问题是我发现的所有进度条都使用ajax的XHR请求。由于表单不是ajax,我似乎找不到跟踪进度的方法。

那么,有没有办法拦截浏览器的内部提交进度,以查看表单上传完成的百分比?

编辑

我在页面开头尝试了以下代码,但不起作用。我想是因为XHR是AJAX的,或者浏览器有自己的需要劫持的功能,但我不知道它会被称为什么,也不知道如果是这样的话该如何使用:

xhr = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", function ( evt )
{
    if( evt.lengthComputable )
    {
        var progressPercent = ( evt.loaded / evt.total ) * 100;
        console.log( value );
    }
}, false );

这是我有时使用的某种类型的渐进增强。它仍然会发出ajax请求,但对用户和开发人员来说都是尽可能透明的。关键是,由于FormData,发布与常规表单发布的数据完全相同的数据,并在我们从服务器收到整页回复时替换整个文档。这是一个未经测试的简化版本:

function enhanceFormWithUploadProgress(form, progress) {
//form : the HTML form element to enhance.
//progress : an HTML element that will display upload progress.
    //testing browser support. if no support for the required js APIs, the form will just be posted naturally with no progress showing.
    var xhr = new XMLHttpRequest();
    if (!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload)) || !window.FormData) {
        return;
    }
    form.addEventListener('submit', function(e) {
        //prevent regular form posting
        e.preventDefault();
        xhr.upload.addEventListener('loadstart', function(event) {
            //initializing the progress indicator (here we're displaying an element that was hidden)
            progress.style.display = 'block';
        }, false);
        xhr.upload.addEventListener('progress', function(event) {
            //displaying the progress value as text percentage, may instead update some CSS to show a bar
            var percent = (100 * event.loaded / event.total);
            progress.innerHTML = 'Progress: ' + percent.toFixed(2) + '%';
        }, false);
        xhr.upload.addEventListener('load', function(event) {
            //this will be displayed while the server is handling the response (all upload data has been transmitted by now)
            progress.innerHTML = 'Completed, waiting for response...';
        }, false);
        xhr.addEventListener('readystatechange', function(event) {
            if (event.target.readyState == 4 && event.target.responseText) {
                //we got a response from the server and we're replacing the whole current document content with it, simulating a page reload
                var newDocument = document.open('text/html', 'replace');
                newDocument.write(event.target.responseText);
                newDocument.close();
            } else {
                throw new Error('Error in the response.');
            }
        }, false);
        //posting the form with the same method and action as specified by the HTML markup
        xhr.open(this.getAttribute('method'), this.getAttribute('action'), true);
        xhr.send(new FormData(this));
    });
};

HTML:

<form method="post">
    <button type="submit">Submit</button>
</form>

JavaScript:

/*
Show a progress element for any form submission via POST.
Prevent the form element from being submitted twice.
*/
(function (win, doc) {
    'use strict';
    if (!doc.querySelectorAll || !win.addEventListener) {
        // doesn't cut the mustard.
        return;
    }
    var forms = doc.querySelectorAll('form[method="post"]'),
        formcount = forms.length,
        i,
        submitting = false,
        checkForm = function (ev) {
            if (submitting) {
                ev.preventDefault();
            } else {
                submitting = true;
                this.appendChild(doc.createElement('progress'));
            }
        };
    for (i = 0; i < formcount; i = i + 1) {
        forms[i].addEventListener('submit', checkForm, false);
    }
}(this, this.document));

演示:http://jsfiddle.net/jsbo6yya/

信用:https://gist.github.com/adactio/9315750