js加php实现文件夹的上传

2018-07-10 10:44:01 3871次 0

HTML


<div class="container" >
    <div id="topbar">
    <div id="filedrag" >Drop file here<div id="progressdiv"></div></div>
    
	<div id="addfilediv">
	   <label class="addfolder"><input type="file" id="folderInput"  multiple="true" webkitdirectory="true" directory="true" style="top: -0.5px; left: -40px; " /></label>
	   <label class="addfile"><input type="file" id="fileselect" name="fileselect[]" multiple="multiple" style="top: -0.5px; left: -40px; " /></label>  
	</div>
	<div id="browse-sort">
	    <a href="#" class="sortable-column-header" id="name-sorter">文件名</a>
	    <a href="#" class="sortable-column-header" id="kind-sorter">类型</a>
	    <a href="#" class="sortable-column-header">最后修改时间</a>
	</div>
	</div>
	<ol id="browse-files">
	</ol>
    
</div>



filedrag.js 通过ajax请求将每个文件单独传过去处理,list.js为列出所有已上传的文件,可忽略。
/*
 filedrag.js - HTML5 File Drag & Drop demonstration
 Featured on SitePoint.com
 Developed by Craig Buckler (@craigbuckler) of OptimalWorks.net
 */
(function() {

    // getElementById
    function $id(id) {
        return document.getElementById(id);
    }
    //判断是否是中文
    function isChinese(temp)
    {
        var re = new RegExp("[u4E00-u9FFF]+","g");
        if(!re.test(temp)) return false ;
        return true ;
    }
    //转码为Unicode
    var GB2312UnicodeConverter={
        ToUnicode:function(str){
            return escape(str).toLocaleLowerCase().replace(/%u/gi,'u');
        }
        ,ToGB2312:function(str){
            return unescape(str.replace(/u/gi,'%u'));
        }
    };




    // file drag hover
    function FileDragHover(e) {
        e.stopPropagation();
        e.preventDefault();
        e.target.className = (e.type == "dragover" ? "hover" : "");
    }


    // file selection
    function FileSelectHandler(e) {
        //hide drag div
        var filedrag = $id("filedrag");
        var browse = $id("browse-files");
//		filedrag.style.display = "none";

        // cancel event and hover styling
        FileDragHover(e);

        var files = e.target.files || e.dataTransfer.files;
        console.log(files);

        // process all File objects  只上传一个文件,可能是中文问题  中文转Unicode
        //无法修改对象的值  重新用另外变量赋值
        for (var i = 0, f; f = files[i]; i++) {
            if(isChinese(f.name)){
                var name=GB2312UnicodeConverter.ToUnicode(f.name);
                var k={};
                k.name=name;
                k.lastModified=f.lastModified;
                k.lastModifiedDate=f.lastModifiedDate;
                k.size=f.size;
                k.type=f.type;
                k.webkitRelativePath=f.webkitRelativePath;
                //console.log(k);
                if(f.type!='')
                    UploadFile(k);
                    //si_createlist(k);

            }else {
                if(f.type!='')
                    UploadFile(f);
                //si_createlist(f);
            }

        }
    }

    // upload JPEG files
    function UploadFile(file) {
        // following line is not necessary: prevents running on SitePoint servers
        if (location.host.indexOf("sitepointstatic") >= 0) return

        var xhr = new XMLHttpRequest();
        if (xhr.upload) {

            xhr.onreadystatechange = callback;
            function callback() {
                if(xhr.readyState ==4 && xhr.status  ==200 ){
                    var data=xhr.responseText
                    console.log(data);
                     data=JSON.parse(data);
                    console.log(data);
                    if (data.status&&$id("upfilename").value!=data.name){
                        $id("upfilename").value=data.name;
                    }
                }
            }
            var name= $id("upfilename").value||'';
            xhr.open("POST", "index.php?c=back&a=upload&name="+name+"&fname="+file.webkitRelativePath, true);
            xhr.setRequestHeader("X-FILENAME", file.name);
            xhr.send(file);

        }

    }

    //folder handler
    function FileFolderHandler(){

    }


    // initialize
    function Init() {

        var folderInput = $id("folderInput");

        // file select
       // fileselect.addEventListener("change", FileSelectHandler, false);
        //folder upload
        folderInput.addEventListener("change",FileSelectHandler,false);

        // is XHR2 available?
        var xhr = new XMLHttpRequest();
        if (xhr.upload) {

            // file drop
           // filedrag.addEventListener("dragover", FileDragHover, false);
            //filedrag.addEventListener("dragleave", FileDragHover, false);
            //filedrag.addEventListener("drop", FileSelectHandler, false);
            //bodytest.addEventListener("dragover",showdragdiv,false);
//			filedrag.style.display = "block";

        }

    }

    // call initialization file
    if (window.File && window.FileList && window.FileReader) {
        Init();
    }
    function showdragdiv(){
        var filedrag = $id("filedrag");
        filedrag.style.display = "block";
    }

})();


php

/*php 并不支持中文文件名  建议少用中文名  */
        function createFolder($path) {
            //$path = iconv('UTF-8', 'gb2312', $path);//解决不能名中文名的问题
            if (!file_exists($path)) {
                mkdir($path,0777);
                createFolder(dirname($path));//递归 实现创建多重文件夹
            }
        }
        $fn = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false);

        if ($fn) {
            //uploaded file name include path
            $fname = $_GET['fname'];
            $name=$_GET['name'];
            //$targetfile = iconv('UTF-8', 'gb2312', Vfile.'/'.dirname($fname));//支持中文名
            if ($fname!=''&& $fname!='undefined') {
                //修改文件夹名称
                $names=explode('/',$fname);
                if(!empty($name)&&$names[0]!=$name){
                    $fname= str_replace($names[0], $name, $fname);
                    //$names[0]=$name;
                }
                $targetfile = iconv('UTF-8', 'gb2312', Vfile.'/'.$fname);//支持中文名
                createFolder(dirname($targetfile));
            }else{
                $targetfile = iconv('UTF-8', 'gb2312', Vfile.'/'.$fn);
                $names=explode('/',$fn);
            }
            $gfname=iconv('UTF-8', 'gb2312',__DIR__.'/Views/file'.$fname);
            /*文件已存在,退出上传*/
            if(file_exists($gfname)) {
                echo json_encode(array('status'=>0,'msg'=>'该文件已存在!'));
                exit();
            }
            // AJAX call
            if (file_put_contents($targetfile,file_get_contents('php://input'))){
                echo json_encode(array('name'=>$names[0],'status'=>1));
            }else{
                echo json_encode(array('status'=>0));
            }


        }
        else {

            // form submit
            $files = $_FILES['fileselect'];
            print_r($files);
            foreach ($files['error'] as $id => $err) {
                if ($err == UPLOAD_ERR_OK) {
                    $fn = $files['name'][$id];
                    move_uploaded_file(
                        $files['tmp_name'][$id],
                        Vfile.'/'. $fn
                    );
                    echo "

File $fn uploaded.

"; } } }


总结:该功能并未够完善,还有比较多的漏洞。刚开始,有中文名的文件时都会中断传输(火狐、UC浏览器如此 ),后来将所 有中文转为Unicode,解决了该问题。1.在php中也不支持中文,将上传的文件夹重命名为中文名时,php再次获取查看中文名,没问题 ,但进入相应的文件查看该文件夹时乱码(文件夹,原本是中文名的文件并没问题);2.每次传输文件到php进行新建文件与文件 夹时总报错说文件夹已存在,但所有文件在创建之前已判断文件夹是否存在(…… 3.php传回来的文件名只有第一个字母 另:网上并未出现比较好的上传文件夹功能的例子,大多有错误,并且大部分是js加Java实现的(并不熟悉)


后来解决了……


完善中:

1、增加的时候文件名存在时跳出ajax的循环不再进行上传。

过程:在后台方面处理好了,在文件名存在时不进行创建创建文件,但js部分,是将所有文件遍历后一个个传到后台的,这时,在进行第一个请求获取到文件名已存在时,就跳出该循环,但现在的ajax是异步请求,只能通过回调函数获取到数据,无法再函数外面获取到值,函数内部无法跳出该循环。

想法:将ajax改为同步

实施:改为异步也不行


发表评论

注:*为必填

回复 的评论
*
选择
*
*