基於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主題,不影響本文相關的配置代碼邏輯git

<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('更新視頻失敗');
        };

    }

其他的一些操做的配置:github

  • 得到已上傳資源的訪問連接ajax

    1. (手動)經過請求路由」域名(分佈式啓用時應當爲儲存服務器的域名)/aetherupload/display/「+file1 訪問file1
    2. (自動)經過全局幫助方法 aetherupload_display_link(file1) 訪問file1
    3. (自動)經過工具類方法 AetherUploadUtil::getDisplayLink(file1) 訪問file1
  • 得到已上傳資源的下載連接redis

    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秒傳記錄。bootstrap

相關文章
相關標籤/搜索