首页 文章

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

提问于
浏览
68

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

A Google search for html5 drag-and-drop file uploading -gmail给出了类似的东西:

所有这些指南都使用 FileReader (或Firefox 3.6不推荐使用 getAsBinary ,这也没有其他浏览器支持) .

但是,Google最近发布了Gmail更新,允许在Chromium以及Firefox和Chromium does not have FileReader上传文件上传 . 我每晚都在使用最新的Chromium,它可以拖放上传文件,但不支持 FileReader .

我见过有人提到可以通过拖动到 <input type="file" /> 来实现拖放上传,但是一次只能支持一个文件,而Gmail 's uploader can handle multiple files being dragged onto it, so that'显然不是他们正在做的事情 .

所以问题是,他们是如何做到的?你如何支持Chromium进行HTML5文件上传?另外,你能支持Safari吗?

9 回答

  • 33

    警告: This is compatibility code for very old versions of Safari and Chrome. 现代浏览器都支持FileReader API;这是一个教程:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

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


    一种可能是使用the method used in 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 中,用于"pseudo-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" /> 元素上),并且可以与Firefox 3.6的HTML5 drop 事件结合使用 .

    我不知道这是否是Gmail使用的方法,但它肯定也有效 .

  • 0

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

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

    • Chunking

    • Drag/Drop

    • PNG调整大小

    • JPEG调整大小

    • 类型过滤

    • 流上传

    • 分段上传

    • 文件大小限制

    • 上传进度

    对于以下大多数技术:

    • Flash

    • 齿轮

    • HTML 5

    • Silverlight

    • BrowserPlus

    是的,since 2010.05.27,它支持在Chrome测试版上运行HTML5的拖放功能 .

  • 0

    经过很多很多 Sleuth 工作之后,我在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:

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

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

  • 2

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

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

    希望这对一些人有帮助 .

  • 13

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

    它适用于Firefox,Safari和Chrome .

  • 2

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

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

    你不需要设置边界或任何头部,就像这样工作正常 . 我在客户端测试了这段代码:firefox 6.02和chrome 13. server:tomcat with“spring mvc”

  • 2

    您可以使用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';
    }
    

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

  • 1

    设置多个属性,如:

    input type =“file”name =“file1”multiple =“multiple”class =“DropHere”

    并使用此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 will now look like

    如果您使用asp.net,您可能也喜欢这篇文章我写的"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

相关问题