Javascript 跟踪基本HTML表单发布进度

Javascript 跟踪基本HTML表单发布进度,javascript,jquery,forms,post,Javascript,Jquery,Forms,Post,我有一个正常提交的基本HTML表单,根本没有ajax。此表单使用常规post提交到同一文件。我不使用AJAX,因为表单有12个文本字段和至少1个图像,但最多可能有26个图像,而且AJAX不能同时处理表单和图像,我必须保存到数据库中,使用AJAX需要做很多额外的工作 问题是我需要以某种方式跟踪表单上传进度。大多数程序员都知道在浏览器的左下角或右下角查看表单提交进度。但大多数人不知道这一点 所以我想显示一个进度条。问题是我发现的所有进度条都使用ajax的XHR请求。由于表单不是ajax,我似乎找不到

我有一个正常提交的基本HTML表单,根本没有ajax。此表单使用常规post提交到同一文件。我不使用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 );
HTML:


提交
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));
/*
通过POST显示任何表单提交的进度元素。
防止表单元素提交两次。
*/
(功能(win、doc){
"严格使用",;
如果(!doc.queryselectoral | |!win.addEventListener){
//不要切芥末。
返回;
}
var forms=doc.querySelectorAll('form[method=“post”]”),
formcount=forms.length,
我
提交=错误,
检查形式=功能(ev){
如果(提交){
ev.preventDefault();
}否则{
提交=真;
这个.appendChild(doc.createElement('progress'));
}
};
对于(i=0;i
演示:


信用证:

这是我有时使用的某种渐进式增强。它仍然会发出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));

    });

};

你可以试着用一个进度条在谷歌上搜索某个库来完成这个上传,这将大大减少你自己滚动的痛苦。这很好,但它是一个来回的进度条。它并没有真正显示上传的实际进度。它只是来回滴答地响。我需要当前上传的完整进度。如果没有AJAX,这是不可能的-您需要来自文件上传完成的服务器的某种响应(或者来自服务器的关于当前上传进度的响应)-这将通过AJAX完成。从表面上看,您只向服务器发送一个单独的HTTP POST,您将只收到一个HTTP响应(即,当回发后重新加载页面时)。如果您的堆栈是PHP,那么请阅读本文:-您可以使用AJAX上传文件,一旦触发了完整的事件,表单的其余部分就有效了。这里必须有一些方法来劫持浏览器所拥有的内容。浏览器栏显示文件上载的进度。因此,在浏览器中的某个地方有此信息。@J53请阅读HTTP请求-响应模式的工作原理,特别是
input[type=“file”]
元素在处理表单数据(即多部分表单数据)时的处理方式。我知道浏览器栏显示了进度百分比,但出于安全原因,有些东西JavaScript不应该访问,Chrome/FF/任何东西的内部都肯定是其中之一。@jfreak53这是一个很好的教程,可以使用xhr和HTML5文件API实现这一点:每第n次,都会提交一个表单,以上代码正在提交n次。
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));

    });

};