一.用input控件实现拖放上传
<form action="http://localhost:82/drag&drop/fileUpload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="myfile" id="">
<input type="submit" value="上传文件">
</form>
注意:必须设置method="POST"
、enctype="multipart/form-data"
以及type="file" name="myfile"
,三者缺少任何一个都会导致后端PHP无法收到数据
当然,把文件拖放上去之后,点击submit按钮,然后浏览器显示忙状态,页面就开始刷新。用提交表单的方式无法避免上传文件时的页面刷新,后面介绍的方式可以实现无刷新拖放上传
(后端代码与FormData + Ajax方式相同,请看后文)
二.用FormData + Ajax实现拖放上传
<div id="dropArea3">文件放置区域</div>
<script>
// 可拖放元素
var area3 = document.getElementById('dropArea3');
// 文件放置区域
area3.ondragover = function(e) {
e.preventDefault();
}
area3.ondrop = function(e) {
e.preventDefault();
var files = e.dataTransfer.files;
if (files && files.length > 0) {
// 输出文件信息
var str = '';
for(var i = 0; i < files.length; i++) {
var file = files[i];
// 在线预览图片也需要先把图片上传到服务器,因为无法获取客户端文件url
// 上传文件直接xhr发送file对象即可
var formData = new FormData();
formData.append('myfile', file);
// JQ方式
// $.ajax({
// type : 'POST',
// url: 'http://localhost:82/drag&drop/fileUpload.php',
/* 必须设置下面两个属性,否则会导致$_FILES收不到数据 */
// processData: false,
// contentType: false,
// data: formData,
// success: function(res){
// console.log('success');
// console.log(res);
// },
// error: function(res) {
// console.log('error');
// }
// });
// 原生JS方式
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:82/drag&drop/fileUpload.php", true);
/* 千万不能设置,会导致$_FILES收不到数据 */
// xhr.setRequestHeader('Content-Type', 'multipart/form-data');
xhr.send(formData);
xhr.onload = function(e) {
if (this.status == 200) {
console.log(this.responseText);
}
};
console.log(file);
}
console.log('receive a file');
}
}
</script>
上面代码介绍了两种方式:JQuery和原生JS。看代码可以发现,其实用原生JS更方便(要注意千万不能设置ContentType),毕竟需要注意的这一点很容易误打误撞成功。而JQuery的实现方式则不好理解(必须设置processData和contentType为false,这怎么可能想得到。。)。
所以,建议采用原生JS来实现这部分,至于兼容性,支持拖放文件的浏览器也应该早就支持标准xhr了
三.后端处理
首先明确一点,虽然Ajax发送文件用的是POST方法,但发送的毕竟是文件(有一些额外的属性),不是普通串。所以PHP后端是用$_FILES
数组来接收的,而不是$_POST
数组
<?php
/* 从$_FILES中取,而不是$_POST */
$file = $_FILES['myfile'];
$fileName = $file['name'];
// echo $fileName;
$fileSize = $file['size'];
// echo $fileSize;
if ($fileName != "") {
$rand = rand(100, 999);
$pics = date("YmdHis") . $rand . $fileName;
//上传路径
$filePath = "files/". $pics;
/* tmp_name是定死的,php出于服务器安全性考虑,过滤文件名 */
if (move_uploaded_file($_FILES['myfile']["tmp_name"], $filePath)) {
echo $filePath;
}
}
?>
注意上面的多行注释内容,尤其是move_uploaded_file
函数的参数,不知道的话是肯定写不对的
参考资料:
- 前辈博文若干