在 Google Chrome/Chromium 和 Safari 中拖放文件上传?

IT技术 javascript ajax html
2021-03-03 11:02:42

拖放文件上传可以在 Firefox 3.6 中完成。

谷歌搜索html5 拖放文件上传 -gmail给出如下内容:

所有这些指南都使用FileReader(或 Firefox 3.6 的 deprecated getAsBinary,其他浏览器也不支持)。

然而,谷歌最近发布了 Gmail 的更新,允许在 Chromium 和 Firefox 中拖放文件上传,而Chromium 没有FileReader. 我每晚都在使用最新的 Chromium,它可以拖放上传文件,但不支持FileReader.

我看到有人提到拖放上传可以通过拖放到一个<input type="file" />,但一次只能支持一个文件,而 Gmail 的上传器可以处理被拖到它上面的多个文件,所以这显然不是他们想要的正在做。

那么问题来了,他们是怎么做到的?你们如何支持 Chromium 上传 HTML5 文件?另外,能支持Safari吗?

6个回答

警告:这是非常旧版本的 Safari 和 Chrome 的兼容性代码。现代浏览器都支持 FileReader API;这是一个教程:https : //developer.mozilla.org/en-US/docs/Using_files_from_web_applications

此代码现在仅在出于某种原因需要支持 Safari 5 及更早版本或 Chrome 6 及更早版本时才有用。


一种可能性是使用SwellJS 中使用的方法

<input type="file" multiple="multiple" />像这样使用

<form method="post" enctype="multipart/form-data" id="uploadform">
  <input type="file" name="dragupload[]" multiple="multiple"
  onchange="if (this.value) document.getElementById('uploadform').submit();" />
</form>

输入元素的样式可以设置为opacity: 0(绝对)在接受上传的元素上。整个表单可以放在一个iframe类似于“伪 Ajax”的行为中。上传元素可以是一个隐藏的图层,直到有东西拖到它上面。

这样的 iframe 看起来像:

<script>
<!--
  var entered = 0;
-->
</script>
<body ondragenter="entered++;document.getElementById('uploadelement').style.display='block'" ondragleave="entered--;if (!entered) document.getElementById('uploadelement').style.display='none'">
  <form method="post" enctype="multipart/form-data" id="uploadform">
    Things can be dragged and dropped here!
    <input type="file" id="uploadelement" name="dragupload[]" multiple="multiple" onchange="if (this.value) { document.getElementById('uploadform').submit(); }" style="display:none;position:absolute;top:0;left:0;right:0;bottom:0;opacity:0;" />
  </form>
</body>

这应该仅在检测到 Safari 或 Chrome 时执行(因为其他浏览器不支持拖放到<input type="file" />元素上),并且可以与dropFirefox 3.6+的 HTML5事件结合使用

我不知道这是否是 Gmail 使用的方法,但它当然也适用。

感谢您对这篇文章。您可以从这里链接到完整示例吗?一个可能包括服务器端代码?或者只是解释(在 asp.net 上)我如何访问从这个表单(“uploadForm”)提交的文件
2021-04-29 11:02:42
显示/隐藏代码上的条目计数递增/递减技巧非常方便。
2021-05-08 11:02:42

您可能对更符合技术和浏览器的内容感兴趣。

在我看来,Plupload做得很好,支持以下功能:

  • 分块
  • 拖放
  • PNG 调整大小
  • JPEG 调整大小
  • 类型过滤
  • 流上传
  • 分段上传
  • 文件大小限制
  • 上传进度

对于以下大多数技术:

  • flash
  • 齿轮
  • HTML 5
  • silverlight
  • 浏览器增强版

是的,从 2010.05.27 开始,它支持在 Chrome beta 上运行的 HTML5 的拖放。

对我来说:在 html5 运行时,FF 15.0.1 有效;Chrome 21 没有。
2021-04-21 11:02:42
HTML5 上传对我来说也适用于 WinXp 上的 Chrome 8.552.210 Beta(只有几个月,他们有 2 个版本)。无论如何感谢您的帖子!
2021-05-03 11:02:42
哦?您是否尝试过此页面的“HTML 5 运行时”?plupload.com/example_all_runtimes.php
2021-05-04 11:02:42
HTML5 运行时版本适用于 OS X 上的 6.0.472.25 dev。它似乎也适用于 Firefox 4 beta。
2021-05-18 11:02:42

经过大量、大量、大量的侦探工作后,我在 Chrome 中找到了一些工作。适用于 Chrome。在 Safari 上,它会冻结。在 Firefox 上,它不会让我删除文件。IE 会打开丢弃的文件。即使在 Chrome 中,由于某种原因,拖放也只能进行一次,之后您必须刷新页面。(一个可能的原因是事件处理程序有问题。)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            window.onload = function () {
                var div = document.getElementById('div');
                div.ondragenter = div.ondragover = function (e) {
                    e.preventDefault();
                    e.dataTransfer.dropEffect = 'copy';
                    return false;
                }
                div.ondrop = function (e) {
                    for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                        var file = e.dataTransfer.files[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)

                        var xhr = new XMLHttpRequest;
                        xhr.open('post', 'handler.php', true);
                        xhr.onreadystatechange = function () {
                            if (this.readyState != 4)
                                return;
                            document.body.innerHTML += '<pre>' + this.responseText + '</pre>';
                        }
                        xhr.setRequestHeader('Content-Type', 'multipart/form-data');
                        xhr.setRequestHeader('X-File-Name', file.fileName);
                        xhr.setRequestHeader('X-File-Size', file.fileSize);
                        xhr.send(file); // For some reason sending the actual File object in Chrome works?
                    }

                    e.preventDefault();
                    return false;
                }
            }
        </script>
    </head>
    <body>
        <div id="div" style="width: 100%; height: 200px; border: 1px solid blue">Drop here</div>
    </body>
</html>

处理程序.php:

    // This is not a true file upload. Instead, it sends the raw data directly.
    echo htmlentities(file_get_contents('php://input'));
效果很好,一个 gmail 开发人员告诉我你应该使用 dropEffect='move' for FF3.6+,还没有在 FF 中测试过,所以不确定这是否仍然需要
2021-05-04 11:02:42
使用 document.body.innerHTML += 会破坏 dom 事件。避免这种情况将解决您的问题。
2021-05-18 11:02:42

您不需要使用 iframe 来执行伪 ajax 上传。Chrome 和 Safari 都支持带有进度事件的XHR2 上传,因此您可以制作进度条等。

...是的,这很明显。这里的问题是我见过的所有教程都使用FileReadergetAsBinary()(即 Chrome 不支持的功能)来 XHR2 上传文件。我怀疑这是必需的,所以我在这里所做的基本上是询问如果有人想要 Chrome 支持,会怎么做。
2021-05-19 11:02:42

对于我们自己的应用程序,我们仅对 FireFox 进行拖放操作。我们为其他人恢复到传统的 iframe 上传。为了检测是否支持拖放,我们运行以下代码:

if (typeof(window.File) == 'object' && typeof(window.FileReader) == 'function' && typeof(window.FileList) == 'object') {
   // DnD is supported!
}

希望这对一些人有帮助。

您确实提到您只为 FireFox 执行拖放操作,但对于可能使用此代码的其他人,Safari 5 (Windows) 将返回 false 进行window.FileReader检查,即使它处理文件丢失的情况非常好。仍在寻找可靠的浏览器功能检测文件拖放...
2021-04-25 11:02:42