HTML5文件拖拽上传

swordray 2010-08-08

通过HTML的文件API ,Firefox、Chrome等浏览器已经支持从操作系统直接拖拽文件,并上传到服务器。相对于使用了十多年的HTML表单,这是一个革命性的进步。虽然IE的落后让很多开发者还在观望中,但是Gmail邮箱的附件拖拽功能已经给部分用户带来了极大的方便,而需要大量上传文件的CMS(内容管理系统)也将会从中受益。

 

让我们看一下Firefox 是如何使用拖拽上传功能的:

 

首先提供一个区域来放置文件

 

<div name="image" id="dropbox" style="min-width:300px;min-height:100px;border:3px dashed silver;"></div>

 

然后监听拖拽过程中的dragenter、dragleave、drop等事件

 

	document.addEventListener("dragenter", function(e){
		dropbox.style.borderColor = 'gray';
	}, false);
	document.addEventListener("dragleave", function(e){
		dropbox.style.borderColor = 'silver';
	}, false);
	dropbox.addEventListener("dragenter", function(e){
		dropbox.style.borderColor = 'gray';
		dropbox.style.backgroundColor = 'white';
	}, false);
	dropbox.addEventListener("dragleave", function(e){
		dropbox.style.backgroundColor = 'transparent';
	}, false);
	dropbox.addEventListener("dragenter", function(e){
		e.stopPropagation();
		e.preventDefault();
	}, false);
	dropbox.addEventListener("dragover", function(e){
		e.stopPropagation();
		e.preventDefault();
	}, false);
	dropbox.addEventListener("drop", function(e){
		e.stopPropagation();
		e.preventDefault();
		
		handleFiles(e.dataTransfer.files);
		
		submit.disabled = false;
	}, false);
 

其中最主要的是drop事件中用handleFiles()依次处理所有文件

 

	handleFiles = function(files) {
		for (var i = 0; i < files.length; i++) {
			var file = files[i];

		}
	}
 

对于图片类型的文件可以直接读取内容,显示预览图

 

			if (!file.type.match(/image*/)) {
				continue;
			}
			
			var img = document.createElement("img");
			img.classList.add("obj");
			img.file = file;
			preview.appendChild(img);
			
			var reader = new FileReader();
			reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
			reader.readAsDataURL(file);
 

接下来就是核心功能:ajax上传。首先新建一个XHR请求

 

		var xhr = new XMLHttpRequest();
		xhr.open('post', '/file/upload', true);
 

监听上传进度和完成事件

 

		xhr.upload.addEventListener("progress", function(e) {
			if (e.lengthComputable) {
				var percentage = Math.round((e.loaded * 100) / e.total);
				img.style.opacity = 1-percentage/100.0;
			}
		}, false);
		
		xhr.upload.addEventListener("load", function(e){
			
		}, false);

 

最后把数据模拟成multipart/form-data的格式上传

 

		xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); // simulate a file MIME POST request.
		xhr.setRequestHeader("Content-Length", fileSize);
		
		var body = '';
		body += "--" + boundary + "\r\n";
		body += "Content-Disposition: form-data; name=\""+dropbox.getAttribute('name')+"\"; filename=\"" + fileName + "\"\r\n";
		body += "Content-Type: "+fileType+"\r\n\r\n";
		body += fileData + "\r\n";
		body += "--" + boundary + "--\r\n";
		
		xhr.sendAsBinary(body);
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

西门吹牛 2010-08-10
ie不支持,都是浮云!
dayone 2010-08-10
浮云不浮云,先玩玩再说
rainsilence 2010-08-10
在chrome 下怎么send?
hanz188 2010-08-10
如果能搭配几个效果图来看看比较好。
sentryward 2010-08-12
不错,支持一记!
interjc 2010-08-12
谁说IE不支持,支持老IE不支持罢了,你下个IE9试试,什么东西都是IE不支持就不做,技术能进步?
tomcatlee 2010-08-12
用gmail测试,firefox和chrome都可以,ie8不行
miaojihao 2010-08-13
Serena999 写道
tomcatlee 写道
用gmail测试,firefox和chrome都可以,ie8不行

JavaEye Q 群
1号群 39211996  已满
2号群 62336899  已满
3号群 7736086   已满
4号群 1894459   已满
5号群 89686356  已满
6号群 68123515  可加
7号群 30903453  可加
8号群 106553317 可加
9号群 110222079 可加

我们一共有20个群 就贴这些
我们还有专门的女程序员群
我们还给介绍对象
我们还给介绍工作

Java开发工程师

Java架构师

测试工程师

测试架构师

测试经理

ETL开发工程师

ETL架构师

运维工程师

mysql DBA

PHP开发工程师

以上职位要求4年以上经验
待遇在年薪15万到25万之间
符合要求的加我 Qq 280155570

Global site tag (gtag.js) - Google Analytics