Search code examples
angularjslaravelzipblob

I cant download a zip file in AngularJS (from Laravel response)


I am trying to download a zip file from a Laravel API using Angular JS. I do not believe the issue is from Laravel.

Basically when the response comes and the download trigger is made it does not know its a .zip file, however the file itself is good. But then when I manually add the .zip extension in Angular JS in the file name the browser advises its a corrupt file.

If I do not add the extension, it downloads fine, and then if i rename the file with no extension in Windows and change it to test.zip it works perfectly as a zip file. This is how I know the data is good.

I have tried arraybuffer responseType and blob. With blob I am getting the download trigger, with arraybuffer nothing is happening (including no console errors).

Here is my JS controller code:

vm.downloadSelectedFiles = function() {
    vm.selectedFiles = [];
    angular.forEach(vm.fileDownloadList, function(value,index) {
        if(value==1) {
            vm.selectedFiles.push(index);
        }
    });
    Data.downloadSelectedFiles(vm.selectedFiles,vm.stationIDToLookUp)
     .then(function (data) {
        var url = $window.URL || $window.webkitURL;
        vm.fileUrl = url.createObjectURL(data.data);
        var a = document.createElement("a");
        a.href = vm.fileUrl;
        a.download = 'test.zip';
        //a.download = 'test';
        a.click();

    }).catch(function (err) {
    });
}

Here is my JS service code

    downloadSelectedFiles: function downloadSelectedFiles(selectedFiles,stationID) {
        var apiBase = apiUrl + 'download-selected-files';
        var config = {
            //responseType: 'arraybuffer'
            responseType: 'blob'
        };
        var data = {
            selectedFiles: selectedFiles,
            stationID: stationID
        }

        return $http.post(apiBase, data, config);
    }

And just in case there is something relevant about the response from the API. Here is my Laravel code

public function downloadSelectedFiles(PublishDataRequest $requestData) {
    return response()->file(storage_path() . '/app/files/test.zip');
}

Solution

  • Try setting the MIME type to application/zip:

    Data.downloadSelectedFiles(vm.selectedFiles,vm.stationIDToLookUp)
     .then(function (response) {
        var blob = response.data;
        var zipBlob = new Blob([blob], { type: "application/zip" });
        var url = $window.URL || $window.webkitURL;
        vm.fileUrl = url.createObjectURL(zipBlob);
        var a = document.createElement("a");
        a.href = vm.fileUrl;
        a.download = 'test.zip';
        //a.download = 'test';
        a.click();
    }).catch(function (response) {
        console.log("ERROR", response);
        throw response;
    });