β

文件拖放上传

黯羽轻扬 82 阅读

一.用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 函数的参数,不知道的话是肯定写不对的

参考资料:

作者:黯羽轻扬
原文地址:文件拖放上传, 感谢原作者分享。