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

     2023-03-05     278

关键词:

【中文标题】在 Google Chrome/Chromium 和 Safari 中拖放文件上传?【英文标题】:Drag-and-drop file upload in Google Chrome/Chromium and Safari? 【发布时间】:2011-02-09 02:27:18 【问题描述】:

在 Firefox 3.6 中可以进行拖放文件上传。

A Google search for html5 drag-and-drop file uploading -gmail 给出如下内容:

Native Drag + Drop file upload in Firefox 3.6 http://www.appelsiini.net/2009/10/html5-drag-and-drop-multiple-file-upload http://www.thecssninja.com/javascript/drag-and-drop-upload

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

不过,Google 最近发布了 Gmail 更新,允许在 Chromium 和 Firefox 和 Chromium does not have FileReader 中拖放文件上传。我用的是最新的Chromium nightly,可以拖拽上传文件,但不支持FileReader

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

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

【问题讨论】:

P.S.阅读源代码非常困难,因为 Gmail 的源代码由于他们对其进行的所有优化而被很好地混淆了。 P.P.S. HTML <input type="file" />FileList 是只读的,因此您也不能将拖放的文件移植到其中一个。 这篇文章的标题可以改吗?我刚刚发布了一个重复的问题,询问“Chrome”中的“拖放”,但它与这个问题不匹配,因为标题使用 Chromium(大多数人不使用)。 好的,我改了标题。 【参考方案1】:

警告:这是非常旧版本的 Safari 和 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 中,用于类似“伪 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 时才应该这样做(因为其他浏览器不支持拖放到 &lt;input type="file" /&gt; 元素上),并且可以与 Firefox 3.6 的 HTML5 drop 事件结合使用+。

我不知道这是否是 Gmail 使用的方法,但它确实也可以。

【讨论】:

显示/隐藏代码中的条目计数递增/递减技巧非常方便。 感谢您的这篇文章。您是否可以从此处链接到完整示例?一个可能包括服务器端代码?或者只是解释(在 asp.net 上)我如何访问从这个表单(“uploadForm”)提交的文件【参考方案2】:

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

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

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

适用于以下大多数技术:

闪光 齿轮 HTML 5 银光 BrowserPlus

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

【讨论】:

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

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

【讨论】:

使用 document.body.innerHTML += 会破坏 dom 事件。避免这种情况将解决您的问题。 效果很好,一个 gmail 开发人员告诉我,你应该对 FF3.6+ 使用 dropEffect='move',还没有在 FF 中测试过,所以不确定这是否仍然需要【参考方案4】:

您不需要使用 iframe 来进行伪 ajax 上传。 Chrome 和 Safari 都支持 XHR2 uploads 和进度事件,所以你可以做进度条等。

【讨论】:

...是的,这很明显。这里的问题是我见过的所有教程都使用FileReadergetAsBinary()(即Chrome 不支持的功能)来XHR2 上传文件。我怀疑这是必需的,所以我在这里基本上要做的是询问如果想要 Chrome 支持该怎么做。【参考方案5】:

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

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

希望这对某些人有所帮助。

【讨论】:

您确实提到您仅对 FireFox 进行拖放,但对于可能使用此代码的其他人,Safari 5 (Windows) 将为 window.FileReader 检查返回 false,即使它处理文件滴得很好。仍在为文件拖放寻找可靠的浏览器功能检测...【参考方案6】:

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

它适用于 Firefox、Safari 和 Chrome。

【讨论】:

【参考方案7】:

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

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

你不需要设置边界或任何头部,这样就可以了。 我在 客户端:firefox 6.02 和 chrome 13。 服务器:带有“spring mvc”的tomcat

【讨论】:

【参考方案8】:

您可以使用 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/) 尽情享受吧:)

【讨论】:

【参考方案9】:

设置多个属性如:

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;

文件字段现在看起来像:

如果你使用asp.net你可能也会喜欢我写的这篇文章“带进度条和拖放的多文件上传”:http://www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress-bar-and-drag-an

【讨论】:

有没有办法在 javascript 中检测 Chrome/Chromium/V8 分析器是不是正在运行?

】有没有办法在javascript中检测Chrome/Chromium/V8分析器是不是正在运行?【英文标题】:IsthereawaytodetectinjavascriptiftheChrome/Chromium/V8profilerisrunning?有没有办法在javascript中检测Chrome/Chromium/V8分析器是否正在运行?【发布时间】:2019-03-28... 查看详情

如何使用更改和删除事件在 firefox 和 chrome/chromium 上上传和列出目录

】如何使用更改和删除事件在firefox和chrome/chromium上上传和列出目录【英文标题】:Howtouploadandlistdirectoriesatfirefoxandchrome/chromiumusingchangeanddropevents【发布时间】:2017-02-0113:03:04【问题描述】:mozilla和webkit浏览器现在都允许上传目... 查看详情

Chrome/Chromium 中奇怪的对角线(错误?)

】Chrome/Chromium中奇怪的对角线(错误?)【英文标题】:StrangediagonallinesinChrome/Chromium(bug?)【发布时间】:2017-06-1605:10:03【问题描述】:当我使用CSS过滤器、阴影、变换、SVG(或类似的)时,我的Chrome/Chromium显示一条奇怪的对角... 查看详情

Windows 上的 HTML5 地理位置比 Linux(Firefox、Chrome、[Chromium])更准确

】Windows上的HTML5地理位置比Linux(Firefox、Chrome、[Chromium])更准确【英文标题】:HTML5geolocationmoreaccurateonWindowsthanLinux(Firefox,Chrome,[Chromium])【发布时间】:2012-12-1014:10:37【问题描述】:我一直在使用HTML5地理定位,并注意到我在Windo... 查看详情

树梅派:安装chrome/chromium

貌似最新版2016-9-23版本的系统,已经自带chromium浏览器了,如果你不想重新安装系统,可以按照本文的方法来安装。网上的教程大部分已经失效,apt-getinstallchromium命令无效,因为这浏览器已经改名字了,用以下命令安装:apt-getup... 查看详情

<ul><li> 中的 display:table 获取 vertical-align:middle of <a> 项目会产生 Chrome/Chromium 问题

】<ul><li>中的display:table获取vertical-align:middleof<a>项目会产生Chrome/Chromium问题?【英文标题】:display:tablein<ul><li>togetvertical-align:middleof<a>itemproducesChrome/Chromiumissue?【发布时间】:2013-12- 查看详情

使用 chrome 扩展程序登录网站并从中获取数据

...】:2011-07-1806:19:16【问题描述】:我正在开发一个Chrome/Chromium扩展程序,它将从学校系统读取学校成绩和成绩。问题是该站点不记得登录的用户。因此,我不能使用AJAX。仅当我在其他选项卡上登录到该页面时。但我想在后台自... 查看详情

读《chrome源码剖析》,对其架构设计有感

...,果然技术都是互通有无的。文章目录前言谷歌Chrome/Chromium的多进程架构Chrome的线程模型进程间通信方式前言它是 查看详情

是否有访问 Chrome 同步数据的 API? [关闭]

...访问,比如说,你的Chrome同步书签,我是否必须对Chrome/Chromium使用的界面进行逆向工程?或者是否有为此发布的API?【问题讨论】:试试这个问题:***. 查看详情

如何在html中嵌入pdf文件?

...已经尝试了以下两个。在Firefox上运行良好,但在chrome、chromium和android浏览器上运行良好。<embedtype="application/pdf"src="myfile. 查看详情

Qt 5.7:使用无头 QWebEngine

...可以在无头模式下将用于打印的html页面呈现为PDF?Chrome/Chromium可以无头运行,应该不是不可能吧?我正在制作一个在我的Linux服务器(没有X)上运行的应用程序,我需要在其中安装37 查看详情

chrome启动后打开第一个网页很慢的解决方案(代码片段)

Chrome启动后打开第一个网页很慢的解决方案Chrome/Chromium以速度快著称,最近每当打开chrome的时候,打开第一个页面都非常慢,往往需要数十秒的时间,经分析,应该是卡在了域名解析这一步了。上网查找资料之后,原来是升级时... 查看详情

前端测试框架puppeteer文档翻译(代码片段)

...peteerpuppeteer是一个通过DevTools协议提供高级API来控制chrome,chromium的NODE库;puppeteer默认运行在headless模式,也可配置后运行在全模式(non-headless).puppeteer可以做什么大部分在浏览器里手动执行的动作都可以通过puppeteer实现!这里有几个列... 查看详情

在 Google 容器中挂载 Google 存储桶

】在Google容器中挂载Google存储桶【英文标题】:MountGooglestoragebucketinGooglecontainer【发布时间】:2016-06-2806:27:31【问题描述】:我想使用gcafuse或任何其他工具/其他规定在GoogleContainerEngine中安装Google存储桶。容器在谷歌容器引擎下... 查看详情

使用 Google 脚本在我的 Google 表格中导入来自 Google 照片的 google 图片

】使用Google脚本在我的Google表格中导入来自Google照片的google图片【英文标题】:ImportinmyGoogleSheetagooglepicturefromGooglePhotoswithGoogleScript【发布时间】:2021-11-1902:04:54【问题描述】:我目前正在从事一个具有多种功能的项目。主要目... 查看详情

Google 字体无法在 Google Chrome 上呈现

】Google字体无法在GoogleChrome上呈现【英文标题】:GoogleFontsarenotrenderingonGoogleChrome【发布时间】:2014-03-2711:53:37【问题描述】:我正在构建一个新的WordPress主题(不知道这是否相关),这个问题一直困扰着我。我已经从GoogleWebfonts... 查看详情

Android - 如何在 Google 地图上为 Google 徽标设置底部填充

】Android-如何在Google地图上为Google徽标设置底部填充【英文标题】:Android-HowtosetbottompaddingforGoogleLogoonGoogleMaps【发布时间】:2018-09-1523:14:47【问题描述】:在iOS中,这很容易。不过,在Android中,我尝试通过android:paddingBottom=80dp&quo... 查看详情

在 Google Play 中显示 Google 游戏服务支持

】在GooglePlay中显示Google游戏服务支持【英文标题】:ShowGoogleGameServicessupportinGooglePlay【发布时间】:2013-07-1112:22:39【问题描述】:我在GooglePlay上发布了一款使用Google游戏服务的游戏。一切正常,但是当我在GooglePlay中查看我的游... 查看详情