创建自定义上传进度条

5
我看过了所有的上传进度条插件、小部件等,它们都很糟糕。它们要么太笨重了,有太多无用的代码,要么就无法正常工作。
我想知道的是,在哪里可以找到关于如何显示简单的上传进度指示器的资料。大多数浏览器都在下面有一个状态进度条,但只使用它与客户打交道并不太专业。
浏览器是如何做到这一点的?我想知道浏览器处理上传文件的内部原理,这样也许我就能使用PHP和jQuery创建一个工具。
谢谢。

确实如此,因为浏览器向网页提供的信息量是(有意)受限的。浏览器进度条在比页面内部进度条更低的层次上工作,因此它具有关于页面状态的更多数据,因此它不那么糟糕(商标)。如果您想构建自己的更好的页面内进度条,请尽管去做。 - Piskvor left the building
在我看来,浏览器栏也很糟糕 - 据我所知,只有Chrome和Opera在进行POST请求时才会显示上传的数据量。 - Piskvor left the building
4个回答

5
由于您想使用PHP,我建议您从uploadprogress扩展开始(PHP默认情况下在上传完成前不会提供任何数据;此扩展提供了这种服务器端功能)。请注意,它需要PHP 5.2+并且对配置选项要求严格。还可以查看其评论和演示以及故障排除提示。PHP文档的注释中提供了一个简短的概述。
使用该扩展,您可以获取一些关于上传的统计信息;然后,您可以通过AJAX轮询服务器并更新某种进度条。
更具体地说:
  • 获取表单的唯一标识符,并将其包含在隐藏字段中
  • 上传应在IFRAME中运行-某些浏览器不允许DOM更新正在运行上传的同一页
  • 通过AJAX轮询服务器(使用标识符指定您感兴趣的上传),并解析结果(如果我没记错,您将得到类似“bytes_uploaded => 123,content-length => 1000”的东西)
  • 更新进度条(您显示它的方式取决于您,我使用“x%完成”加上一个图形栏)
  • 表单上传成功后重定向整个页面
(哦,顺便说一句,请检查PHP的upload_max_filesize和post_max_size设置,因为两者都限制了最大上传大小)

2
使用JavaScript没有可靠的方法来获取文件上传的进度。即使在HTML5中,许多浏览器也缺少对XMLHttpRequest upload.onprogress事件的支持,你不可避免地需要转向Flash或其他文件上传方法。
在询问了这个问题之后,我最终决定使用plupload来满足我的上传需求。

1
确实,仅使用JS没有可靠的方法;如果您可以询问服务器“我们到了吗?”,事情就变得更容易了。 - Piskvor left the building

1

我知道这不是你想要的,但我最近一直在使用plupload进行上传,它似乎非常好,而且不仅依赖于Flash或HTML5。

例如:


  • url是处理页面(php文件)
  • container = 父div或表单,上传按钮所在的位置(设置这个非常重要 - 有一些示例可以说明如何将某些操作附加到plupload执行的特定操作。例如,您可以在下面看到我已经将uploader.start();附加到uploader.start();钩子上。
  • 您还应该能够看到我如何制作自定义上传进度条,通过附加到上传进度钩子

如果你遇到了问题,可以在plupload网站的论坛上提问,他们很擅长回答问题!

$(function(){
    //plupload
    var uploader = new plupload.Uploader({
        runtimes : 'gears,html5,flash',
        browse_button : 'pickfiles',
        container : 'form_2',
        max_file_size : '10mb',
        url : '<?php echo SITE_ROOT ?>plupload/upload.php',
        //resize : {width : 320, height : 240, quality : 90},
        flash_swf_url : '<?php echo SITE_ROOT ?>plupload/js/plupload.flash.swf',
        filters : [
            {title : "Image files", extensions : "jpg,gif,png"}
        ]
    });


uploader.init();

uploader.bind('FilesAdded', function(up, files) {
    uploader.start();
});

uploader.bind('UploadProgress', function(up, file) {
    if(file.percent < 100 && file.percent >= 1){
        $('#progress_bar div').css('width', file.percent+'%');
    }
    else{
        $('#progress_bar').fadeOut(600);
    }                               
});                         

谢谢,我喜欢Plupload,看起来非常酷。但是你是如何将它与PHP页面链接以上传文件的呢?我似乎无法弄清楚。 - michael
我已经更新了我的答案,并附上了我用于调用plupload的脚本。 - Haroldo
除了plupload在没有flash的情况下无法在MSIE上正常工作之外,还有什么其他问题吗? - John Mee

1

Javascript/Ecmascript 无法干扰浏览器原生功能(主要使用 C/C++OS APIs 访问 TCP/UDP sockets)。

要使用 JS 显示进度条,您需要服务器反馈。这可以通过使用服务器 轮询(例如 COMET)来实现。 但是在这一点上,它永远不会像浏览器内置的进度条那样准确。这可能会随着 HTML5 WebSockets 的出现而改变。

要获得准确的结果,您需要持续的连接。您可以 伪造涂金 客户端-服务器请求延迟,但它仍然存在。我不确定 Flash 如何处理这些问题,但我猜它也没有面向连接的流(如果我在这里错了,请纠正我)。


2
Flash知道它已传输了多少字节/需要传输多少字节,并在连接打开和传输时触发事件。这是xhr.upload.onprogress事件(在Firefox 3.5中支持不太稳定)应该提供的功能,但我从未能够可靠地使其工作。 - gnarf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接