乐趣区

关于php:基于Php-Laravel的大文件HTML5分块上传

大文件上传时,往往须要的解决工夫会很长,同时可能会呈现用户中途勾销,网络断开等问题。应用 HTML5 的切片上传技术会无效改善大文件上传时的用户体验,基于 Php Laravel 后端框架和 AetherUpload-Laravel 这个组件,本文尝试去建设一个笼罩前后端的大文件上传计划。

AetherUpload-Laravel 插件 GitHub 仓库

环境

  • Php Laravel 5.8
  • AetherUpload-Laravel 2.0

前端配置

Tips:前端代码中还波及到了 Bootstrap, jasny-bootstrap, Creative-Tim Argon 的 CSS 主题,不影响本文相干的配置代码逻辑

<form ...Your Route config set here...>
<Input ...Other Input...>
<Input ...Other Input...>
<Input ...Other Input...>

<!-- If this part is in edit page I will show the uploaded video, else will show the upload component
The video object I store in database will be like: Video(id, path, screenshot, introduciton, content...) -->

@if($path === '')
<div class="col-xl-6 form-group{{$errors->has('path') ?' has-danger':'' }}"id="aetherupload-wrapper">
    <!-- 组件最内部须要一个名为 aetherupload-wrapper 的 id,用以包装组件 -->
    <label class="form-control-label"> 上传视频 </label>

    <div class="controls">
        <div class="fileinput fileinput-new input-group" data-provides="fileinput"
            style="box-shadow: 0 1px 3px rgba(50, 50, 93, .15), 0 1px 0 rgba(0, 0, 0, .02);">
            <div class="form-control form-control-alternative" data-trigger="fileinput">
                <span class="fileinput-filename"></span>
            </div>
            <span class="input-group-append">

                <span class="input-group-text btn-file" style="border: 0px;">
                    <span class="fileinput-new"> 抉择视频 </span>
                    <span class="fileinput-exists"> 更换视频 </span>
                    <input type="file" id="aetherupload-resource"
                        onchange="console.log(' 更换视频 ');aetherupload(this).setGroup('file').setSavedPathField('#aetherupload-savedpath').setPreprocessRoute('/aetherupload/preprocess').setUploadingRoute('/aetherupload/uploading').setLaxMode(false).success(someCallback).upload()"/>
                </span>
            </span>
        </div>
        <!-- 须要一个名为 aetherupload-resource 的 id,用以标识上传的文件,setGroup(...) 设置分组名,setSavedPathField(...) 设置资源存储门路的保留节点,setPreprocessRoute(...) 设置预处理路由,setUploadingRoute(...) 设置上传分块路由,setLaxMode(...) 设置宽松模式,success(...) 可用于声名上传胜利后的回调办法名。默认为抉择文件后触发上传,也可依据需要手动更改为特定事件触发,如点击提交表单时 -->
        <div class="progress" style="height: 6px;margin-bottom: 2px;margin-top: 10px;width: 200px;">
            <div class="progress-bar bg-primary" id="aetherupload-progressbar"
                style="background-color:#419DF9!important;"></div>
            <!-- 须要一个名为 aetherupload-progressbar 的 id,用以标识进度条 -->
        </div>

        <span style="font-size:12px;color:#aaa;" id="aetherupload-output"></span>
        <!-- 须要一个名为 aetherupload-output 的 id,用以标识提示信息 -->
        <input type="hidden" name="path" id="aetherupload-savedpath" value="{{$path}}">
        <!-- 须要一个自定义名称的 id,以及一个自定义名称的 name 值, 用以标识资源贮存门路主动填充地位,默认 id 为 aetherupload-savedpath,可依据 setSavedPathField(...) 设置为其它任意值 -->
    </div>
    <div id="result"></div>
</div>
@else
    <div class="col-xl-6 form-group">
        <video width="500" height="277" controls>
        <source src="http://127.0.0.1:8000/admin/play/file_201908_4fa4366cd697d28f654254ba599eaeb9.mov" type="video/mp4">
      </video>
    </div>
@endif


<input ...Other Input...>
<input ...Other Input...>
<input ...Other Input...>

</form>

<!-- JS Part Code -->
<script src="{{URL::asset('vendor/aetherupload/js/spark-md5.min.js') }}"></script>
<!--(可选)须要引入 spark-md5.min.js,用以反对秒传性能 -->
<script src="{{URL::asset('vendor/aetherupload/js/aetherupload.js') }}"></script>
<!-- 须要引入 aetherupload.js-->
<script>
    // success(someCallback) 中声名的回调办法需在此定义,参数 someCallback 可为任意名称,此办法将会在上传实现后被调用
    // 可应用 this 对象取得 resourceName,resourceSize,resourceTempBaseName,resourceExt,groupSubdir,group,savedPath 等属性的值
    someCallback = function () {
        // Example Code
        $('#result').append(
            '<p> 执行回调 - 文件已上传,原名:<span >' + this.resourceName + '</span> | 大小:<span >' + parseFloat(this
                .resourceSize / (1000 * 1000)).toFixed(2) + 'MB' + '</span> | 贮存名:<span >' + this.savedPath
            .substr(this.savedPath.lastIndexOf('_') + 1) + '</span></p>'
        );
        // Allow reupload video 容许再次上传新视频笼罩原有的
        $('#aetherupload-resource').attr('disabled', false);
        // Update Video info 像后盾更新本次上传的视频信息
        var video_path = $('#aetherupload-savedpath').val();
        var id = $('#video_id').val();
        var path = "/admin/videos/" + id + '/path';

        $.ajax({
            type: "put",
            url: path,
            data: {'path' : video_path},
            success: function (data) {// location.reload();
                // toastr.success('Success');
            }
        });
    }

</script>

后端配置

public function updatePath(Request $request, $id){$video = Video::find($id);

        <!-- Delete the old video first -->
        if($video->path !== ''){\AetherUpload\Util::deleteResource($video->path);
        }

        $video->path = $request->path;
        if($video->save()){return redirect()->back()->withInput()->with('message', '更新视频胜利');
        }else{return redirect()->back()->withInput()->withErrors('更新视频失败');
        };

    }

其余的一些操作的配置:

  • 取得已上传资源的拜访链接

    1. (手动) 通过申请路由”域名 (分布式启用时该当为贮存服务器的域名)/aetherupload/display/“+file1 拜访 file1
    2. (主动) 通过全局帮忙办法 aetherupload_display_link(file1) 拜访 file1
    3. (主动) 通过工具类办法 AetherUploadUtil::getDisplayLink(file1) 拜访 file1
  • 取得已上传资源的下载链接

    1. (手动) 通过申请路由”域名 (分布式启用时该当为贮存服务器的域名)/aetherupload/download/“+file1+”/newname”下载 file1
    2. (主动) 通过全局帮忙办法 aetherupload_download_link(file1,newname) 下载 file1
    3. (主动) 通过工具类办法 AetherUploadUtil::getDownloadLink(file1,newname) 下载 file1
  • 删除资源

AetherUploadUtil::deleteResource($savedPath); // 删除对应的资源文件
AetherUploadUtil::deleteRedisSavedPath($savedPath); // 删除对应的 redis 秒传记录。

退出移动版