how to implement resumable large file upload in javascript and laravel

1.2k Views Asked by At

I am trying to implement large file upload with resumable.js and laravel-chunk-upload. Everything is working fine, that is I am able to upload large files properly but the problem is, if anything happens to network connection while uploading, then the uploads is not completing properly. one chunk gets error. the error is:

    "message": "fopen(H:\\Codinoz\\Development\\File ECommerce\\digital-product-shopping\\storage\\app\\products/27-09-2021 CMF 20-21 before_166b6fa4934428d2952877c84bed0ef2.): Failed to open stream: Permission denied",

There is no permission problems, because the same function is working properly when there is no network problems.

current javascript code:

let browseFile = $('#browseFile');
let resumable = new Resumable({
    target: '{{ route('files.upload.large') }}',
    query:{_token:'{{ csrf_token() }}'} ,// CSRF token
    //fileType: ['mp4'],
    chunkSize: 10*1024*1024, // default is 1*1024*1024, this should be less than your maximum limit in php.ini
    headers: {
        'Accept' : 'application/json'
    },
    testChunks: false,
    maxChunkRetries: 1000,
    chunkRetryInterval: 2000,
    throttleProgressCallbacks: 1,
});

resumable.assignBrowse(browseFile[0]);

resumable.on('fileAdded', function (file) { // trigger when file picked
    showProgress();
    resumable.upload() // to actually start uploading.
});

resumable.on('fileProgress', function (file) { 
    if(navigator.onLine === true){
        // trigger when file progress update
        updateProgress(Math.floor(file.progress() * 100));
    }
    else{
        alert('no Internet');
    }        
});

resumable.on('fileSuccess', function (file, response) { // trigger when file upload complete
    response = JSON.parse(response)
    console.log('sss');
    //$('#videoPreview').attr('src', response.path);
});

resumable.on('fileError', function (file, response) { // trigger when there is any error        
        console.log(response);
});

let progress = $('.progress');
function showProgress() {
    progress.find('.progress-bar').css('width', '0%');
    progress.find('.progress-bar').html('0%');
    progress.find('.progress-bar').removeClass('bg-success');
    progress.show();
}

function updateProgress(value) {
    progress.find('.progress-bar').css('width', `${value}%`)
    progress.find('.progress-bar').html(`${value}%`)
}

function hideProgress() {
    progress.hide();
}

Laravel Server side code:

public function uploadLargeFiles(Request $request) {
    $receiver = new FileReceiver('file', $request, HandlerFactory::classFromRequest($request));

    if (!$receiver->isUploaded()) {
        // file not uploaded
    }

    $fileReceived = $receiver->receive(); // receive file
    if ($fileReceived->isFinished()) { // file uploading is complete / all chunks are uploaded
        $file = $fileReceived->getFile(); // get file
        $extension = $file->getClientOriginalExtension();
        $fileName = str_replace('.'.$extension, '', $file->getClientOriginalName()); //file name without extenstion
        $fileName .= '_' . md5(time()) . '.' . $extension; // a unique file name

        $disk = Storage::disk(config('filesystems.default'));
        $path = $disk->putFileAs('products', $file, $fileName);

        // delete chunked file
        unlink($file->getPathname());
        return [
            'path' => asset('storage/' . $path),
            'filename' => $fileName
        ];
    }

    // otherwise return percentage information
    $handler = $fileReceived->handler();
    return [
        'done' => $handler->getPercentageDone(),
        'status' => true
    ];
}

I am a beginner in this, so not so good in finding solutions. Tried my best, but couldn't find any solutions. It will be so kind if you could help.

Thank you..

0

There are 0 best solutions below