从浏览器上传多个文件的最佳方法

36

我正在开发一个网络应用程序。用户可以通过HTTP协议上传文件。可以选择使用经典的HTML文件上传控件或Java小程序上传文件。

经典的HTML文件上传不够好,因为只能选择一个文件,而且在实际上传过程中很难获得任何进度指示(最终我使用定时器刷新进度指示器,并通过AJAX调用从服务器获取数据来解决这个问题)。优点是:它总是有效的。

使用Java小程序可以做更多的事情:一次选择多个文件(甚至一个文件夹),压缩文件,获得真正的进度条,在小程序上拖放文件等……但是有几个缺点:

  • 在Mac Safari和Mac Firefox上正确运行它非常困难(感谢Liveconnect)
  • 界面不是完全原生界面,有些人会注意到这一点
  • 小程序的响应不如应该(可能是我的错误,但我觉得一切都很正常)
  • Java UrlConnection类存在一些HTTPS的bug,所以我使用Apache common HTTP客户端进行实际的HTTP上传。这是一个相当大的包,会减慢.jar文件的下载速度
  • Apache common HTTP客户端有时候很难穿过代理
  • Java运行时占用空间相当大

我一直在维护这个Java小程序,但现在我对所有的缺点感到厌烦了,正在考虑编写/购买一个全新的组件来上传这些文件。

问题

如果你有以下要求:

  • 轻松从浏览器上传多个文件,通过HTTP或HTTPS
  • 压缩文件以减少上传时间
  • 上传应该在任何平台上都能工作,并具备原生UI
  • 必须能够上传巨大的文件,至少达到2GB
  • 你可以完全自主选择技术

你会选择哪种技术/组件?


编辑:

  • 给组件拖放文件是一个非常好的附加功能。
  • 看起来有很多与Flash Player相关的问题(swfupload已知问题)。适当的Mac支持和通过带验证的代理上传是我无法没有的选项。这可能会排除所有基于Flash的选项 :-(。
  • 我排除了所有仅使用HTML/Javascript的选项,因为经典的HTML控件无法一次选择多个文件。在想要选择一个文件夹中的多个文件时,点击n次“浏览”按钮很麻烦。

2
关于可恢复上传怎么样?这对我来说似乎非常重要。没有人喜欢在几个小时后重新启动上传失败的文件。 - Arne Evertsson
在这种情况下,我认为您不能再使用Flash,只能使用Java(和Silverlight?) - Sébastien Nussbaumer
大家好,另一款基于Flash的上传工具可以在http://digitarald.de/project/fancyupload/找到。 - user884419
9个回答

5

我最近在Silverlight中实现了一些东西。

基本上使用HttpWebRequest向GenericHandler发送一块数据。

在第一次post时,发送了4KB的数据。在第二个块上,我发送另一个4K块。

当第二个块被接收时,我计算了第一块和第二块之间的往返时间,因此现在发送的第三块将知道如何提高速度。

使用这种方法,我可以上传任意大小的文件,并且可以恢复上传。

每次发送POST请求时,我都会发送以下信息:

[参数] [文件数据]

这里,参数包含以下内容: [块编号] [文件名] [会话ID]

在每个块被接收后,我向我的Silverlight发送一个响应,告诉它花费了多少时间,以便它现在可以发送更大的块。

很难没有代码来解释我的方法,但基本上就是这样做的。

在某个时候,我会写一个快速的说明,介绍我是如何做到这一点的。


听起来很酷,我也想试试。我喜欢我们终于可以使用托管代码在客户端上操作文件!长命白银! - TJB
你是否在 Silverlight 播放器中遇到了有关浏览器 Cookie 管理、代理、平台支持方面的问题? - Sébastien Nussbaumer
Silverlight 运行在客户端,而我的上传处理程序位于服务器端。由于它们都脱离了会话,我需要在启动时将会话 ID 传递给 Silverlight。在上传过程中,会话随后从 Silverlight 传递到处理程序,从而使一切都在一个会话中保持。 - Gautam

5
我从来没有使用过处理2GB大小文件的程序,但是YUI文件上传器在之前的项目中表现得非常出色。您可能还对这个jQuery插件感兴趣。
话虽如此,我仍然认为Java Applet是最好的选择。我认为您将面临比预期更少的可移植性和UI问题,并且拖放功能也非常好用。值得一提的是,Box.net使用Java Applet实现多文件快速上传。

Box.net使用Flash组件作为上传的首选项。该组件随后为希望使用“拖放”功能的用户提供了一个指向Java小程序的链接。 - Sébastien Nussbaumer

3

有很多免费的Flash组件具有良好的多文件上传功能。它们利用ActionScripts FileReference类,配合服务器端的PHP(或其他语言)接收程序。一些最近因FP10的发布而出现故障,但我确定swfupload可以正常工作 :)

希望这能帮到你!


3

好的,这是我的看法

我使用过swfupload进行了一些测试,并且我之前有Java的经验。我的结论是无论使用什么技术,在浏览器上上传都没有完美的解决方案:当上传大文件、通过代理、使用ssl等时,总会出现错误。

但是:

  • Flash上传程序(如swfupload)非常轻巧,不需要用户授权,并具有本地界面,这真的很酷。
  • Java上传程序需要授权,但您可以对用户选择的文件做任何想做的事情(例如压缩),并且拖放功能也很好用。但要准备好调试一些臭虫。
  • 我没有足够时间玩弄Silverlight,也许这就是真正的答案,但这项技术仍然很年轻,所以...如果我有机会稍微摆弄一下Silverlight,我将编辑此帖子。

感谢所有回答!!


1
对于那些几年后找到这个答案的人,我有一点需要注意的。我们多年来一直使用SWFUpload,总体而言,它运行得非常好。需要注意的一件事是,自从Flash Player 9以来,它不会发送授权标头,因此如果您使用集成的Windows身份验证或需要身份验证的代理服务器,则它将无法工作。出于这个原因,我们已经转向基于HTML5的解决方案。 - Martin Wilson

2

是的,我已经听说过JUpload了,但从未有机会或时间进行一些压力测试。我知道通常上传https是个问题(问题在于JDK实现本身。如果JUpload使用默认实现,它可能会受到这个问题的影响)。 - Sébastien Nussbaumer
关于Jumploader:用户界面看起来真的很不错,似乎支持HTTPs。在我看来值得一试 :) - Sébastien Nussbaumer

1

好主意,但有点令人害怕的是它不支持Mac OS X Snow Leopard:雪豹已经发布了2个月!!我会出于好奇尽快在Firefox上尝试一下 ;)谢谢! - Sébastien Nussbaumer

0

有HTTP/HTTPS上传控件,允许多文件上传。这里是Telerik的一个控件,我发现它非常稳定可靠。最新版本看起来具备您所需的大部分功能。


与其他AJAX上传程序不同,这个程序与.NET绑定,因此毫无用处。 - Javier
另外,您不能一次选择一个文件。也许您想谈论的是Telerik Silverlight上传控件。 - Sébastien Nussbaumer

0

你也可以使用HTTP表单上传多个文件,正如Dave已经指出的那样,但如果你想使用一些超越HTTP和Javascript提供的东西,我强烈建议使用Flash。甚至有一些现成的解决方案,比如MultiPowUpload,它提供了许多你所需要的功能。使用Flash客户端获取进度信息比从Javascript发起AJAX调用更容易,因为你有更多的灵活性。


0

1
Apache Commons Fileupload是一个Java服务器端库,用于解析文件上传的HTTP POST请求。我已经让这部分工作正常了。我现在真正关注的是客户端部分。 - Sébastien Nussbaumer

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