大文件上傳時,每每須要的處理時間會很長,同時可能會出現用戶中途取消,網絡斷開等問題。使用HTML5的切片上傳技術會有效改善大文件上傳時的用戶體驗,基於Php Laravel後端框架和AetherUpload-Laravel這個組件,本文嘗試去創建一個覆蓋先後端的大文件上傳方案。前端
AetherUpload-Laravel插件GitHub倉庫
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
得到已上傳資源的下載連接redis
AetherUploadUtil::deleteResource($savedPath); //刪除對應的資源文件
AetherUploadUtil::deleteRedisSavedPath($savedPath); //刪除對應的redis秒傳記錄。bootstrap