4

我已经在 Rails 中建立了一个小型个人网站,并且已经到了需要能够上传文件的地步。这是一项几乎微不足道的任务,根本不需要时间。

需要时间 - 并且正在慢慢削弱我的理智 - 是为用户提供上传进度条的任务。我现在已经看到了至少十几种解决方案,它们似乎都有一个共同点——它们需要在 Web 服务器上安装一个模块。

鉴于我无法控制我的服务器,而且托管公司似乎不太可能安装任何这样的动物,我有点束手无策。真正令人抓狂的是,以任何方式、形式或形式让服务器参与此过程是绝对没有必要的。

想一想:您的浏览器打开一个到远程服务器的套接字并开始发送数据。您的浏览器确切地知道要发送多少字节,并且由于 TCP 确认的魔力,还知道有多少字节已到达服务器端。那么,为什么以“飞行意大利面怪物”的名义,没有简单的方法可以将这些数据呈现给 Javascript,而不会与被炸毁的服务器混为一谈呢?

4

3 回答 3

6

这里真正的限制是 HTML 表单。它们是 10 多年前发明的,当时上传较大的文件似乎完全不可行。因此它们只为您提供一个回调:当整个上传完成时(ACTION 参数)。

幸运的是,有一些免费的基于 Flash 的上传器提供进度条。别担心,它们中的大多数都会优雅地降级(如果用户没有闪存,则提供一个简单的文件上传字段)。所有选项都可以通过 Javascript 控制。而且,它们不需要任何特殊的服务器端基础设施。

检查 swfupload.org

于 2009-06-03T07:26:44.470 回答
2

现在除了 IE(所有版本)之外,几乎所有的网络浏览器都可以。

JavaScript 相当简单。检查 sourceforge.net 上的 webfolder 项目。它显示所有支持 HTML5 的浏览器的上传百分比。

 function upload() {
   document.folder.encoding = "multipart/form-data";
   if (document.folder.file.files) { 
       var xhr = new XMLHttpRequest();
        var fd = new FormData(document.folder);
        /* event listeners */
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false); // loadend if doesn't matter success or not 
        xhr.addEventListener("error", uploadError, false);
        xhr.open("POST", document.folder.action, true);
        fd.append('submit', 'Upload'); // keep consistent with view, so maybe return method in view
        fd.append('background', '1');
        xhr.send(fd); 
        return false;
   }
   return true;
}


function uploadProgress(evt) {
    if (evt.lengthComputable) {
        var per = (evt.loaded*100/evt.total).toFixed(0)+'%';
        getElement('_progress').innerHTML = per;
        document.title = 'Upload ('+per+')';
    }   else {
        getElement('_progress').innerHTML = evt.loaded;
    }
}

function uploadComplete(evt) {
    getElement('_progress').innerHTML = '100%';
    window.location.reload();
}

function uploadError(evt) {
    getElement('_progress').innerHTML = 'error';
}

我还有代码显示具有更多娱乐能力的网站的进度条。

于 2013-04-12T05:50:50.957 回答
0

我完全同意,不幸的是没有跨浏览器的标准 api。但是,即使存在,服务器也需要参与。你不能相信你发送了多少数据,HTTP 需要一个确认。因此,您需要服务器告诉您是否收到了数据报 #526。如果有一个 API,它可能是一个很好的猜测,但不是一回事:S

检查 www.faqs.org/rfcs/rfc1867.html

如果您可以 ping 服务器,您可以模拟它(没有信心)。

于 2009-06-03T06:25:00.813 回答