Laravelとvue前後端分離スライスアップロード


Laravelとvue前後端分離スライスアップロード
  • バックエンドコード
  • public function upload(Request $request)
        {
            $file = $request->file('file');
            $realPath = $file->getRealPath(); //         
            $file_size = $request->input('file_size');
            $blob_num = $request->get('blob_num');
            $total_blob_num = $request->get('total_blob_num');
            $file_name = $request->get('file_name');
            $extension = substr($file_name, strripos($file_name, ".") + 1); //     
            $array = [
                'mp4', 'mov', 'avi', 'rmvb'
            ];
            if (!in_array($extension, $array)) {
                return response()->json(['code' =>  '403', 'msg' =>  '       ']);
            } else {
                //     
                $path = 'slice/' . date('Ymd');
                $filename = $path . '/' . $file_name . '_' . $blob_num;
                //  
                $upload = Storage::disk('public')->put($filename, file_get_contents($realPath));
                //         ,                 
                if ($blob_num == $total_blob_num) {
                    for ($i = 1; $i <= $total_blob_num; $i++) {
                        $blob = Storage::disk('public')->get($path . '/' . $file_name . '_' . $i);
                        file_put_contents(public_path('storage') . '/' . $path . '/' . $file_name, $blob, FILE_APPEND);
                    }
                    //        
                    for ($i = 1; $i <= $total_blob_num; $i++) {
                        Storage::delete('public/' . $path . '/' . $file_name . '_' . $i);
                    }
                }
                if ($upload) {
                    return response()->json([
                        'code'  =>  '200'
                    ]);
                } else {
                    return response()->json([
                        'code'  =>  '400'
                    ]);
                }
            }
        }
    
  • フロントエンドコード
  • <!doctype html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            #progress{
                width: 300px;
                height: 20px;
                background-color:#f7f7f7;
                box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);
                border-radius:4px;
                background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);
            }
    
            #finish{
                background-color: #149bdf;
                background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);
                background-size:40px 40px;
                display: inline-block;
                height: 20px;
            }
            form{
                margin-top: 50px;
            }
        </style>
    </head>
    <body>
    <p id="progress">
        <span id="finish" style="width: 0%;" progress="0"></span>
    </p>
    <form action="" enctype="multipart/form-data">
        <input type="hidden" name="MAX_FILE_SIZE" value="2000000000">
        <input type="file" name="file" id="file">
        <input type="button" value="  " id="stop">
    </form>
    <script>
        var fileForm = document.getElementById("file");
        var stopBtn = document.getElementById('stop');
        var upload = new Upload();
    
        fileForm.onchange = function(){
            upload.addFileAndSend(this);
        }
    
        stopBtn.onclick = function(){
            this.value = "   ";
            upload.stop();
            this.value = "   ";
        }
    
        function Upload(){
            var xhr = new XMLHttpRequest();
            var form_data = new FormData();
            const LENGTH = 1024 * 1024 * 5;
            var start = 0;
            var end = start + LENGTH;
            var blob;
            var blob_num = 1;
            var is_stop = 0
    
            //    ,      
            this.addFileAndSend = function(that){
                var file = that.files[0];
                blob = cutFile(file);
                sendFile(blob,file);
                blob_num  += 1;
            }
    
            //      
            this.stop = function(){
                xhr.abort();
                is_stop = 1;
            }
    
            //    
            function cutFile(file){
                var file_blob = file.slice(start,end);
                start = end;
                end = start + LENGTH;
                return file_blob;
            };
    
            //    
            function sendFile(blob,file){
                var form_data = new FormData();
                var total_blob_num = Math.ceil(file.size / LENGTH);
                form_data.append('file',blob);
                form_data.append('blob_num',blob_num);
                form_data.append('total_blob_num',total_blob_num);
                form_data.append('file_name',file.name);
                form_data.append('file_size',file.size);
                xhr.open('POST','http://www.laravel7.com/api/upload',false);
    
                xhr.onreadystatechange  = function () {
                    if (xhr.readyState==4 && xhr.status==200)
                    {
                        console.log(xhr.responseText);
                    }
    
                    var progress;
                    var progressObj = document.getElementById('finish');
                    if(total_blob_num == 1){
                        progress = '100%';
                    }else{
                        progress = Math.min(100,(blob_num/total_blob_num)* 100 ) +'%';
                        // console.log(progress);
                        // console.log('  ');
                    }
                    progressObj.style.width = progress;
                    var t = setTimeout(function(){
                        if(start < file.size && is_stop === 0){
                            blob = cutFile(file);
                            sendFile(blob,file);
                            blob_num  += 1;
                        }else{
                            setTimeout(t);
                        }
                    },1000);
                }
                xhr.send(form_data);
            }
        }
    
    </script>
    </body>
    </html>