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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2657653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:21:05  来源:igfitidea点击:

Drag-and-drop file upload in Google Chrome/Chromium and Safari?

javascriptajaxhtml

提问by Zarel

Drag-and-drop file uploading can be done in Firefox 3.6.

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

A Google search for html5 drag-and-drop file uploading -gmailgives things like:

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

All of these guides use FileReader(or the Firefox 3.6's deprecated getAsBinary, which no other browser supports, either).

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

However, Google recently released an update for Gmail that allowed drag-and-drop file uploading in Chromium as well as Firefox, and Chromium does not have FileReader. I'm using the latest Chromium nightly, and it can drag-drop upload files, while not supporting FileReader.

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

I've seen someone mention that drag-drop uploading can be possible by dragging onto an <input type="file" />, but that can only support one file at a time, while Gmail's uploader can handle multiple files being dragged onto it, so that's clearly not what they're doing.

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

So the question is, how do they do it? How do you support Chromium for HTML5 file uploading? In addition, can you support Safari?

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

采纳答案by Zarel

WARNING: This is compatibility code for very old versions of Safari and Chrome.Modern browsers all support the FileReader API; here's one tutorial: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

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

This code is now only useful if for some reason you have a need to support Safari 5 and older, or Chrome 6 and older.

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



One possibility is to use the method used in SwellJS:

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

Use <input type="file" multiple="multiple" />like so:

<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>

The input element can be styled to have opacity: 0and positioned (absolutely) over an element that accepts uploads. The entire form can be placed inside an iframefor "pseudo-Ajax" like behavior. And the upload element can be a layer hidden until something is dragged over it.

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

Such an iframe would look like:

这样的 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>

This should only be done when Safari or Chrome is detected (since other browsers don't support drag-and-drop onto <input type="file" />elements), and can be used in combination with the HTML5 dropevent for Firefox 3.6+.

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

I can't tell if this is the method Gmail uses, but it certainly works about as well.

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

回答by Arnaud Leymet

You may be interested on something more technology- and browser-compliant.

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

Seems to me that Pluploaddoes it well, supporting the following features:

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

  • Chunking
  • Drag/Drop
  • PNG Resize
  • JPEG Resize
  • Type filtering
  • Stream upload
  • Multipart upload
  • File size restriction
  • Upload progress
  • 分块
  • 拖放
  • PNG 调整大小
  • JPEG 调整大小
  • 类型过滤
  • 流上传
  • 分段上传
  • 文件大小限制
  • 上传进度

for most of the following technologies:

对于以下大多数技术:

  • Flash
  • Gears
  • HTML 5
  • Silverlight
  • BrowserPlus
  • 闪光
  • 齿轮
  • HTML 5
  • 银光
  • 浏览器增强版

And yes, since 2010.05.27, it supports drag/drop for HTML5 running on Chrome beta.

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

回答by Casey Chu

I've got something working in Chrome after much, much, much detective work. This onlyworks on Chrome. On Safari, it freezes. On Firefox, it won't let me drop the file. IE opens the dropped file instead. Even in Chrome, the drag and drop only works once, for some reason, after which you have to refresh the page. (A possible reason for this is that something is wrong with the event handlers.)

经过大量、大量、大量的侦探工作,我在 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>

handler.php:

处理程序.php:

    // This is not a true file upload. Instead, it sends the raw data directly.
    echo htmlentities(file_get_contents('php://input'));

回答by Ryan Seddon

You wouldn't need to use an iframe to do pseudo ajax uploading. Chrome and Safari both support XHR2 uploadswith progress events so you can do progress bars etc.

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

回答by Martin

For our own application, we do drag and drop for FireFox only. We revert to the traditional iframe upload for others. In order to detect that drag and drop is supported, we run this code:

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

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

Hope this is helpful to some.

希望这对一些人有帮助。

回答by WOj

You can use html5uploader library: http://code.google.com/p/html5uploader/

您可以使用 html5uploader 库:http: //code.google.com/p/html5uploader/

It works with Firefox, Safari and Chrome.

它适用于 Firefox、Safari 和 Chrome。

回答by summer

The latest browser support file upload well. You could use:

最新的浏览器支持文件上传很好。你可以使用:

xhr = new XMLHttpRequest();     
xhr.open('POST', targetPHP, true);
var formData = new FormData();
formData.append('upload',file);
xhr.send(formData);

You do not need to set boundary or any head,just like this it works fine. I tested this code in client:firefox 6.02 and in chrome 13. server:tomcat with "spring mvc"

你不需要设置边界或任何头部,就像这样它工作正常。我在 client:firefox 6.02 和 chrome 13 中测试了这段代码。 server:tomcat with "spring mvc"

回答by Igor Krupitsky

Set multiple attribute like:

设置多个属性,如:

input type="file" name="file1" multiple="multiple" class="DropHere"

input type="file" name="file1" multiple="multiple" class="DropHere"

and use this CSS DropHere class:

并使用这个 CSS DropHere 类:

.DropHere
{
    height: 100px;
    padding: 3px;
    border: 2px dashed #555;
    border-radius: 5px;
    cursor: default;
    background-image:url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='100px' width='220px'><text x='55' y='75' font-size='20'>or drop files here</text></svg>");
    background-repeat: no-repeat;
}

The file field will now look like:

文件字段现在看起来像:

The file will now look like

该文件现在看起来像

If you use asp.net you might also like this article I wrote "Multiple file upload with progress bar and drag and drop": http://www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress-bar-and-drag-an

如果您使用 asp.net,您可能还会喜欢这篇我写的“带进度条和拖放的多文件上传”文章:http: //www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress -酒吧和拖拉式

回答by tai

you can use FormData to store the File, then upload it. e.g

您可以使用 FormData 存储文件,然后上传它。例如

function setUp(){
  var dropContainer = document.getElementById("container");
  dropContainer.addEventListener("drop",dropHandler,false);
  dropContainer.addEventListener("dragenter", function(event){event.stopPropagation();event.preventDefault();}, false);
  dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
  dropContainer.addEventListener("drop", dropHandler, false);
  getResult()
}
function dropHandler(event){
  var files = event.dataTransfer.files;
  var count = files.length;
  form = new FormData();
  for(var i= 0;i<count;i++){
    form.append("file"+i, files[i]);
  }
  sendData();
}
function sendData(){
  var xhr = new XMLHttpRequest();  
  xhr.upload.addEventListener("progress", uploadProgress, false);  
  xhr.addEventListener("load", uploadComplete, false);
  xhr.addEventListener("error", uploadFailed, false);  
  xhr.open("POST", "/upload");
  xhr.send(form);
  var progressBar = document.getElementById('progressBar');
  progressBar.style.display = 'block';
  progressBar.style.width = '0px';
}

the demo is here(http://flexinnerp.appspot.com/) just enjoy it :)

演示在这里(http://flexinnerp.appspot.com/)只是享受它:)