最近项目需要无刷新上传文件的模块,虽然已有现成的JQuery插件来解决这样的问题,但是想从原生的代码开始,探讨其中的机制。
在支持HTML5的浏览器上,通过拖拽文件,并且通过已有的file API可以实现很不多的效果。主要的知识点是:
1 拖拽问题
document,Element的拖拽,阻止浏览器的默认行为,同时给drop事件添加处理函数。
area.addEventListener('dragenter',function(e){
e.stopPropagation();
e.preventDefault();
area.style.borderColor = 'blue';
},false);
2 上传问题
使用FormData构造form,同时通过XMLHttpRequest来实现上传
var xhr = new XMLHttpRequest();
xhr.open('post','upload.php',true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
var fd = new FormData();
fd.append('userfile',file);
xhr.send(fd);
但是对于IE这种不支持HTML5的浏览器而言,就需要换一套机制,默认的处于安全考虑,ajax是不允许操作文件的,那些ajax文件上传的插件的机制基本上都是:通过form进行上传,同时将target指向一个隐藏的iframe,通过iframe向服务器提交请求。
同时,另外一个问题也出现了,如何判断文件上传完毕,或者说,如何得到服务器端回传的数据,当然这个数据会显示在iframe,问题是如何得到这里面的数据,这里有2个需要注意的问题:
1 iframe数据的读取
通过iframe.contentWindow.document.body.innerHTML 来读取,这个这普通的DOM稍有不同。
2 采用什么机制读取
通俗的说就是如何知道数据是什么时候回传的,只有数据回传完毕之后才能读取。一种方法是采用定时器不停的读取内容,判断内容是否为空;
这种方式和轮询有点类似,笔者也是从那个里面得到启示的;而另外一种方式则采用事件机制onreadystatechange,通过判断readyState == 'complete'判断数据是否回传完毕了当然这种方式的一个bug就是,页面刚加载时,iframe也发生了statechange事件,所以这里也要做一个判断,判断数据内容是否为空。
var hidframe = document.getElementById('hidframe');
hidframe.onreadystatechange= function(){
if(this.readyState == 'complete'){
var content = this.contentWindow.document.body.innerHTML;
if(content){
alert(content);
}
}
};
本文探讨了HTML5环境下文件的拖拽上传机制,包括原生JavaScript实现的拖拽效果及上传过程。针对不支持HTML5的浏览器,文章还介绍了通过iframe实现文件上传的方法,并讨论了如何判断上传完成及获取服务器响应。

2820

被折叠的 条评论
为什么被折叠?



