如何将文件上传到服务器:多个文件和自定义UI

时间:2013-06-20 20:13:14

标签: javascript html

我正在尝试实现一个UI,让最终用户在自定义用户界面上上传多个文件服务器 - 就像GMail或Outlook.net一样。

节点很少:

  1. <input type="file">很丑陋 - 而不是标准(IE在文件名左侧显示名为“浏览”的按钮.Chrome在文件名右侧显示名为“选择”的按钮。)< / LI>
  2. 大多数建议如何建议用户界面建议使用opacity=0隐藏输入文件元素,但最好是使用自定义用户界面。 'click'事件将打开对话框,返回时文件名(没有路径)将作为$('#file')。val()。请参阅this问题,以及jsfiddle上的示例。
  3. 我也知道HTML5现在有一个multiple="multiple"属性,可以让用户选择多个文件。
  4. 但是,我正在寻找一个多文件解决方案,它将适用于IE8及以上版本(以及WebKit,Mozila)。
  5. 有人建议Google使用Flash。这不是真的。当禁用闪存时,他们的多文件上传工作正常。
  6. 现在,我最大的惊喜是:在IE和Chrome上使用开发人员工具(F12),同时查看GMail和Outlook.NET - 两个实现都没有<input type='file'>元素树(据我所知)。此外,这两种实现都适用于IE8(禁用闪存)。

    发生了什么事?他们是怎么做到的?

    编辑:为什么我认为他们不使用文件输入元素?打开开发人员工具(F12),切换到控制台,键入:document.getElementsByTagName('input')。有24个输入元素,其中19个是type = hidden,none是type = file。

    编辑2:谢谢所有响应者和评论员。确实 - 下面的“没有别的办法”论点(在评论中)是有效的。事实证明,Outlook.NET和GMail都有一个<input type='file'>元素,只有当用户点击“附加文件”按钮时,它们才会动态添加。然后,他们将向元素发送“click”事件,这将触发选择文件对话框。

    见证这一点,使用F12开发工具(在Chrome或IE中),并在交互式控制台中输入:document.querySelectorAll('input [type = file]')。请注意,在两个实现中,元素都是body的直接子元素(display = none)。

    他们使用iframe进行上传(与下面的唯一答案不同),但现在可以在HTML5中上传简单的XHR代码。

    网上有关如何执行此操作的最佳资源是:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications。我已经完成了以下@Jay的步骤(这很棒),但Mozilla页面更简单,这是我的推荐。另外,快速浏览@Niranjan评论中的jsfiddle示例。

1 个答案:

答案 0 :(得分:2)

我最近为旧的asp.net网站实现了一个多文件上传UI,但概念应该是相同的。

我不擅长写作(总结代码),但现在就去了。

  1. 创建多个IFrame。由于安全限制,我在加载文档后尝试编写IFrame时遇到问题,因此,尽管用户会立即使用,但服务器的渲染次数仍然很多。

  2. 添加“上传”按钮和处理程序,该按钮和处理程序首先将load处理程序添加到其中一个iframe中。

    var frame = $('iframe:first');

  3. 框架负载处理程序中的

    ---

    frame.load(function () { /* all the code below* /});
    

    2.A。将文件的输入标记以及您喜欢的其他元素写入框架中​​,如此

    frame.contents().find('body').html("html goes here");
    

    2.b中。现在为框架中的文件输入添加一个处理程序并提交该表单:

    frame.contents().find('#fileUpload').change( /*submit the form */)
    

    2.C。现在调用文件上传对话框

    frame.contents().find('#fileUpload').click();
    

    2.D。现在该行将阻塞,直到对话框返回。在这种情况下,您必须检查null的文件上传控件的值,以防它们取消。这是我将iframe标记为未使用的地方。

    2.E。以太方式你需要从iframe的加载解除绑定并重新绑定到另一个处理返回的方法(上传完成)

    frame.unbind('load');
    frame.load(function () { /* handle file uploaded */})
    

    2.e.1。这是我向用户报告成功并释放框架以便可以重复使用的地方。

    2.e.2。最后从上传完成方法再次解除加载

    所有这些都在您的框架加载处理程序

    3.现在导致框架加载

    frame.load();
    

    至少我是怎么做到的。我将所有文件上传到处理程序,该处理程序报告了文件%,并且父页面内的循环触发了ajax获取并显示每个文件的进度。

    主要的想法是,如果您希望以“ajaxy”风格上传多文件但不使用Flash或Html 5,则需要使用iframe和一些花哨的脚本集合。

    希望这有帮助。