首页 > 如何实现百度网盘前端上传文件夹的功能,他们的文件夹上传用的什么组件,求大神指点

如何实现百度网盘前端上传文件夹的功能,他们的文件夹上传用的什么组件,求大神指点

如何实现百度网盘上传文件夹的功能,他们的文件夹上传用的什么组件能够将目录结构传给后台,一般文件上传都是无序的,求大神指点

上传文件夹用 HTML5 Upload Folder With Webkitdirectory

相关链接如下
http://sapphion.com/2011/11/21/html5-folder-upload-with-webkitdirectory/
http://sapphion.com/2012/06/12/keep-directory-structure-when-uploading/

关于文件或文件夹上传的代码如下,要做的是把目录结构传给后台,目录结构和文件对应,现在的上传文件都是无序的,难点是没法做到对应,参数不知道放哪里

<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-upload fade">
        {% if (file.error) { %}
            <td class="name">{%=file.name%}</td>
            <td class="size">{%=o.formatFileSize(file.size)%}</td>
            <td class="error"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else if (o.files.valid && !i) { %}
            <td class="name">
                {%=file.name%}
                <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
            </td>
            <td class="size">{%=o.formatFileSize(file.size)%}</td>
            <td class="start">{% if (!o.options.autoUpload) { %}
                <button class="btn btn-success">
                    <span class="icon-upload"></span>
                    <span>{%=locale.fileupload.start%}</span>
                </button>
            {% } %}</td>
        {% } else { %}
            <td class="name">{%=file.name%}</td>
            <td class="size">{%=o.formatFileSize(file.size)%}</td>
            <td></td>
        {% } %}
        <td class="cancel">{% if (!i) { %}
            <button class="btn btn-warning">
                <span class="icon-ban-circle"></span>
                <span>{%=locale.fileupload.cancel%}</span>
            </button>
        {% } %}</td>
    </tr>
{% } %}
</script>
<!-- The template to display files after upload -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
        {% if (file.error) { %}
            <td class="name">{%=file.name%}</td>
            <td class="size">{%=o.formatFileSize(file.size)%}</td>
            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}:</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else { %}
            <td class="name">{%=file.name%}</td>
            <td class="size">{%=o.formatFileSize(file.size)%}</td>
            <td colspan="2"></td>
        {% } %}
    </tr>
{% } %}
</script>
var cur_path = "{{path|escapejs}}";
$(function() {
    $.getScript('{{ MEDIA_URL }}js/jquery.fileupload.min.js', function () {
        var popup = $('#upload-file-dialog').addClass('fixed-upload-file-dialog');;
        var popup_height = '200px';
        popup.css({'height': popup_height}).data('height', popup_height);

        var fu_status = $('.status', popup),
            total_progress = $('.total-progress', popup),
            cancel_all_btn = $('.fileupload-buttonbar .cancel', popup),
            close_icon = $('.close', popup),
            saving_tip = $('.saving-tip', popup);

        var fu_status_ = {
            'uploading': "{% trans "File Uploading..." %}",
            'complete': "{% trans "File Upload complete" %}",
            'canceled': "{% trans "File Upload canceled" %}",
            'failed': "{% trans "File Upload failed" %}"
        };

        popup.fileupload({
            formData: {'parent_dir': cur_path},
            fileInput: $('#upload-file input'),
            paramName: 'file',
            // customize it for 'done'
            getFilesFromResponse: function (data) {
                if (data.result) {
                    return data.result;
                }
            },
            autoUpload:true,
            {% if max_upload_file_size %}
            maxFileSize: {{ max_upload_file_size }}, // in bytes
            {% endif %}
            maxNumberOfFiles: 500,
            sequentialUploads: true
        })
        .bind('fileuploadadd', function(e, data) {
            popup.removeClass('hide');
            cancel_all_btn.removeClass('hide');
            close_icon.addClass('hide');
        })
        .bind('fileuploadstart', function() {
            fu_status.html(fu_status_.uploading);
        })
        .bind('fileuploadsubmit', function(e, data) {
            if (data.files.length == 0) {
                return false;
            }
            var file = data.files[0];
            // get url(token) for every file
            if (!file.error) {
                $.ajax({
                    url: '{% url 'get_file_op_url' repo.id %}',
                    cache: false,
                    data: {
                        'op_type': 'upload',
                        'path': cur_path
                    },
                    dataType: 'json',
                    success: function(ret) {
                        data.url = ret['url'];
                        data.jqXHR = popup.fileupload('send', data);
                    },
                    error: function() {
                        file.error = "{% trans "Failed to get upload url" %}";
                    }
                });
                return false;
            }
        })
        .bind('fileuploadprogressall', function (e, data) {

            if (data.loaded > 0 && data.loaded == data.total) {
                saving_tip.show();
            }
        })
        .bind('fileuploadstop', function() {
            setTimeout(function() { location.reload(true); }, 1000);
        })
        // after tpl has rendered
        .bind('fileuploadcompleted', function() { // 'done'
            if ($('.files .cancel', popup).length == 0) {
                saving_tip.hide();
                total_progress.addClass('hide');
                fu_status.html(fu_status_.complete);
            }
        })
        .bind('fileuploadfailed', function(e, data) { // 'fail'
            if ($('.files .cancel', popup).length == 0) {
                cancel_all_btn.addClass('hide');
                close_icon.removeClass('hide');
                total_progress.addClass('hide');
                saving_tip.hide();
                if (data.errorThrown == 'abort') { // 'cancel'
                    fu_status.html(fu_status_.canceled);
                } else { // 'error'
                    fu_status.html(fu_status_.failed);
                }
            }
        });

        // Enable iframe cross-domain access via redirect option:
        popup.fileupload(
            'option',
            'redirect',
            window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '{{ MEDIA_URL }}cors/result.html?%s')
        );
    });
});

只有chrome支持,我刚才写了点代码测试了一下
前端部分,主要是需要加一个这个只有chrome支持的input属性 webkitdirectory

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
    <script>
        $(function () {
            $("#files").on("change",function (e) {
                $.each(this.files,function (k,v) {
                    console.log(v.type+"="+v.webkitRelativePath);
                });
            });
        })

    </script>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="/index/upload_folder">
    <input type="file" id="files" name="files[]" webkitdirectory mozdirectory>
    <input type="submit" value="确认上传文件夹">
</form>

</body>
</html>

chrome选择文件夹截图

选择完毕效果截图,相当于chrome把里面的文件遍历了一遍,这里有4个文件的原因是macosx文件夹下都会有一个.DS_Store隐藏文件

后端部分用PHP接收了一下,基本和多个file一起提交的效果是一样的
$_FILES直接能拿到,所以我打印了一下$_FILES变量,其他语言的后端应该也是一样的

获取目录结构办法

<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
    <script>
        $(function () {
            $("#files").on("change",function (e) {
                $.each(this.files,function (k,v) {
                    console.log(v.type+"="+v.webkitRelativePath);
                });
            });
        })

    </script>

【热门文章】
【热门文章】