<html>
<head>
<title>XMLHttpRequest</title>
<link href="/stylesheets/style.css" rel="stylesheet" type="text/css">
<script src="/javascripts/jquery-1.7.2.js" type="text/javascript"></script>
<script src="/javascripts/function.js" type="text/javascript"></script>
</head>
<body onload="upload()">
<div id="dropBox" class="droperea" >
<ul id="list"></ul>
<p style="font-size: large;margin-left: 350px;padding-top:110px;" id="txterea">请将文件拖拽到这里上传</p>
</div>
</body>
</html>
1、client使用FormData对象上传或者直接上传文件对象
有关html5拖拽事件:
- dragstart:要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素
- dragenter:拖拽元素进入目标元素时触发,这个事件对象是目标元素
- dragover:拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素
- dragleave:拖拽某元素离开目标元素时触发,这个事件对象是目标元素
- dragend:在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素
- drop:将被拖拽元素放在目标元素内时触发,这个事件对象是目标元素
- 完成一次成功页面内元素拖拽的行为事件过程应该是: dragstart –> dragenter–> dragover –> drop –>dragend
-
//function.js function upload(){ var droperea =document.getElementById("dropBox"); var list=document.getElementById("list"); var txterea=document.getElementById("txterea"); //添加拖拽事件的监听 droperea.addEventListener("dragenter",function(e){ e.preventDefault(); //阻止浏览器的默认行为 droperea.style.backgroundColor = "grey"; },false); droperea.addEventListener("dragleave",function(e){ e.preventDefault(); droperea.style.backgroundColor = "white"; },false); droperea.addEventListener('drop', function(e){ e.stopPropagation(); e.preventDefault(); droperea.style.backgroundColor = "white"; var fileList =e.dataTransfer.files,//获取拖拽文件 fileType = fileList[0].type, fileName = fileList[0].name, fileSize = fileList[0].size, div =document.createElement('div'), reader = new FileReader(); //注意:只有在需要在页面展示图片的时候才需要使用FileReader()这个对象, //这个对象对文件的大小有限制,大概在500MB左右,否则会导致页面崩溃; //如果只是上传一个文件而不需要展示图片的话不需要使用这个对象 // reader.readAsDataURL(fileList[0]);//这里只取拖拽的第一个,实际中你可以遍历处理file列表 // reader.onload = function(e) { div.src=this.result; var formData = new FormData(); var xhr = new XMLHttpRequest(); //因为直接上传文件对象的时候我无法获取文件的信息所以我只能把文件的信息通过param传递过去 var url ="/upload?fileName=" +fileName+'&fileSize='+fileSize; console.log(fileList[0]); formData.append("uploadFile",fileList[0]); xhr.open('POST',url, true); xhr.onload = function(e) {}; // Listen to the uploadprogress. var progressBar =document.querySelector('progress'); xhr.upload.onprogress = function(e) { if(e.lengthComputable) { var percentComplete =parseInt((e.loaded / e.total) * 100); console.log("Upload: " +percentComplete + "% complete"); div.innerHTML="name : "+fileName+' ' +percentComplete + "%"; } }; // xhr.send(formData); //使用multipart/form-data格式上传 xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");//直接发送文件对象的时候使用 xhr.setRequestHeader("X-File-Name",encodeURIComponent(fileName)); xhr.setRequestHeader("Content-Type","application/octet-stream"); xhr.send(fileList[0]);//直接上传文件对象, // xhr.abort();//表示取消文件上传 list.a(div);//复制代码的时候把.a改成 txterea.style.display="none"; // }; reader.onabort=function(e){ //取消文件上传时触发 alert('File readcancelled'); }; //其他的一些事件reader.onerror,reader.onloadstart, //reader.readAsBinaryString(e.target.files[0]); },false); droperea.addEventListener('dragover',function(e) { e.stopPropagation(); e.preventDefault(); },false); } function abortRead() { reader.abort(); // 取消浏览器读取本地文件 }
2、server处理上传的文件:
在服务器端使用express处理的时候要主要一个问题,它对req.headers[content-length]有大小的限制,如果我们使用默认设定的话只有20mb。一旦超出20mb就会报错:
所以如果文件较大我们需要自己设定它:可以在varapp = express();下面加一句
app.use(express.limit('800mb'));不可以写在
app.configure里面这是我试验出来的暂时还没找到原因。
(1)处理使用formdata上传的数据;
exports.upload=function(req,res){
console.log(req.headers);
console.log(req.files);
var tmp_path = req.files.uploadFile.path; // 获得文件的临时路径
var target_path = './public/upload/' +req.files.uploadFile.name;// 指定文件上传后的目录
fs.rename(tmp_path, target_path, function(err) { // 移动文件
if (err) throw err;
fs.unlink(tmp_path, function() {// 删除临时文件夹文件,
if (err) throw err;
res.end();
});
});
};
(2)处理使用直接上传文件对象方法上传的数据:
var projectPath=__dirname.substring(0,__dirname.indexOf("/routes"));//取得项目的路径
exports.upload =function(req, res,next) {
var fileName=req.param('fileName');//获取param中文件的信息
var fileSize=req.param('fileSize');
var target_path =projectPath+'/public/upload/' + fileName ;
var wOption = {flags: 'w',encoding: null,mode: 0777};
var fileStream = fs.createWriteStream(target_path,wOption);
req.pipe(fileStream, { end: false });
req.on('end', function() {
console.log("传输完毕!");
var transfer;
fs.stat(target_path, function (err, data) {
if (err) throw err;
transfer=String(data.size);
console.log("tmp file's size :",data.size);
console.log("the received size is :",fileSize);
if(transfer==String(fileSize)){
res.send({success:true});
}else{
res.send({error:"文件在传输的过程中有丢失,传输失败!"});
}
});
});
};