Pertanyaan Download file sederhana Angularjs menyebabkan router untuk redirect


HTML:

<a href="mysite.com/uploads/asd4a4d5a.pdf" download="foo.pdf">

Upload mendapatkan nama file yang unik sementara nama asli disimpan dalam basis data. Saya ingin mewujudkan unduhan file sederhana. Tetapi kode di atas mengalihkan ke / karena:

$routeProvider.otherwise({
    redirectTo: '/', 
    controller: MainController
});

Saya mencoba dengan

$scope.download = function(resource){
    window.open(resource);
}

tetapi ini hanya membuka file di jendela baru.

Ada gagasan cara mengaktifkan unduhan nyata untuk semua jenis file?


75
2018-05-21 13:04


asal


Jawaban:


https://docs.angularjs.org/guide/$location#html-link-rewriting

Dalam kasus seperti berikut ini, tautan tidak ditulis ulang; sebaliknya, the   browser akan melakukan pemuatan ulang halaman penuh ke tautan asli.

  • Tautan yang mengandung elemen target Contoh:
    <a href="/ext/link?a=b" target="_self">link</a> 

  • Tautan absolut yang mengarah ke domain berbeda. Contoh:
    <a href="http://angularjs.org/">link</a> 

  • Tautan yang dimulai dengan '/' yang mengarah ke jalur basis yang berbeda ketika basis ditentukan. Contoh:
    <a href="/not-my-base/link">link</a>

Jadi dalam kasus Anda, Anda harus menambahkan atribut target seperti ...

<a target="_self" href="example.com/uploads/asd4a4d5a.pdf" download="foo.pdf">

111
2018-05-21 13:40



Kami juga harus mengembangkan solusi yang bahkan akan bekerja dengan API yang membutuhkan otentikasi (lihat artikel ini)

Menggunakan AngularJS secara singkat di sini adalah bagaimana kami melakukannya:

Langkah 1: Buat direktif yang berdedikasi

// jQuery needed, uses Bootstrap classes, adjust the path of templateUrl
app.directive('pdfDownload', function() {
return {
    restrict: 'E',
    templateUrl: '/path/to/pdfDownload.tpl.html',
    scope: true,
    link: function(scope, element, attr) {
        var anchor = element.children()[0];

        // When the download starts, disable the link
        scope.$on('download-start', function() {
            $(anchor).attr('disabled', 'disabled');
        });

        // When the download finishes, attach the data to the link. Enable the link and change its appearance.
        scope.$on('downloaded', function(event, data) {
            $(anchor).attr({
                href: 'data:application/pdf;base64,' + data,
                download: attr.filename
            })
                .removeAttr('disabled')
                .text('Save')
                .removeClass('btn-primary')
                .addClass('btn-success');

            // Also overwrite the download pdf function to do nothing.
            scope.downloadPdf = function() {
            };
        });
    },
    controller: ['$scope', '$attrs', '$http', function($scope, $attrs, $http) {
        $scope.downloadPdf = function() {
            $scope.$emit('download-start');
            $http.get($attrs.url).then(function(response) {
                $scope.$emit('downloaded', response.data);
            });
        };
    }] 
});

Langkah 2: Buat template

<a href="" class="btn btn-primary" ng-click="downloadPdf()">Download</a>

Langkah 3: Gunakan itu

<pdf-download url="/some/path/to/a.pdf" filename="my-awesome-pdf"></pdf-download>

Ini akan membuat tombol biru. Ketika diklik, PDF akan diunduh (Perhatian: backend harus mengantarkan PDF dalam pengkodean Base64!) Dan dimasukkan ke dalam href. Tombol berubah menjadi hijau dan mengalihkan teks ke Menyimpan. Pengguna dapat mengklik lagi dan akan disajikan dengan dialog file unduhan standar untuk file tersebut my-awesome.pdf.

Contoh kami menggunakan file PDF, tetapi tampaknya Anda dapat memberikan format biner apa pun yang diberikan dengan benar dienkode.


32
2017-09-25 07:47



Jika Anda memerlukan arahan yang lebih canggih, saya merekomendasikan solusi yang saya laksanakan, diuji dengan benar di Internet Explorer 11, Chrome, dan FireFox.

Saya berharap itu, akan sangat membantu.

HTML:

<a href="#" class="btn btn-default" file-name="'fileName.extension'"  ng-click="getFile()" file-download="myBlobObject"><i class="fa fa-file-excel-o"></i></a>

DIRECTIVE:

directive('fileDownload',function(){
    return{
        restrict:'A',
        scope:{
            fileDownload:'=',
            fileName:'=',
        },

        link:function(scope,elem,atrs){


            scope.$watch('fileDownload',function(newValue, oldValue){

                if(newValue!=undefined && newValue!=null){
                    console.debug('Downloading a new file'); 
                    var isFirefox = typeof InstallTrigger !== 'undefined';
                    var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
                    var isIE = /*@cc_on!@*/false || !!document.documentMode;
                    var isEdge = !isIE && !!window.StyleMedia;
                    var isChrome = !!window.chrome && !!window.chrome.webstore;
                    var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
                    var isBlink = (isChrome || isOpera) && !!window.CSS;

                    if(isFirefox || isIE || isChrome){
                        if(isChrome){
                            console.log('Manage Google Chrome download');
                            var url = window.URL || window.webkitURL;
                            var fileURL = url.createObjectURL(scope.fileDownload);
                            var downloadLink = angular.element('<a></a>');//create a new  <a> tag element
                            downloadLink.attr('href',fileURL);
                            downloadLink.attr('download',scope.fileName);
                            downloadLink.attr('target','_self');
                            downloadLink[0].click();//call click function
                            url.revokeObjectURL(fileURL);//revoke the object from URL
                        }
                        if(isIE){
                            console.log('Manage IE download>10');
                            window.navigator.msSaveOrOpenBlob(scope.fileDownload,scope.fileName); 
                        }
                        if(isFirefox){
                            console.log('Manage Mozilla Firefox download');
                            var url = window.URL || window.webkitURL;
                            var fileURL = url.createObjectURL(scope.fileDownload);
                            var a=elem[0];//recover the <a> tag from directive
                            a.href=fileURL;
                            a.download=scope.fileName;
                            a.target='_self';
                            a.click();//we call click function
                        }


                    }else{
                        alert('SORRY YOUR BROWSER IS NOT COMPATIBLE');
                    }
                }
            });

        }
    }
})

DI CONTROLLER:

$scope.myBlobObject=undefined;
$scope.getFile=function(){
        console.log('download started, you can show a wating animation');
        serviceAsPromise.getStream({param1:'data1',param1:'data2', ...})
        .then(function(data){//is important that the data was returned as Aray Buffer
                console.log('Stream download complete, stop animation!');
                $scope.myBlobObject=new Blob([data],{ type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
        },function(fail){
                console.log('Download Error, stop animation and show error message');
                                    $scope.myBlobObject=[];
                                });
                            }; 

DALAM PELAYANAN:

function getStream(params){
                 console.log("RUNNING");
                 var deferred = $q.defer();

                 $http({
                     url:'../downloadURL/',
                     method:"PUT",//you can use also GET or POST
                     data:params,
                     headers:{'Content-type': 'application/json'},
                     responseType : 'arraybuffer',//THIS IS IMPORTANT
                    })
                    .success(function (data) {
                        console.debug("SUCCESS");
                        deferred.resolve(data);
                    }).error(function (data) {
                         console.error("ERROR");
                         deferred.reject(data);
                    });

                 return deferred.promise;
                };

BACKEND (pada SPRING):

@RequestMapping(value = "/downloadURL/", method = RequestMethod.PUT)
public void downloadExcel(HttpServletResponse response,
        @RequestBody Map<String,String> spParams
        ) throws IOException {
        OutputStream outStream=null;
outStream = response.getOutputStream();//is important manage the exceptions here
ObjectThatWritesOnOutputStream myWriter= new ObjectThatWritesOnOutputStream();// note that this object doesn exist on JAVA,
ObjectThatWritesOnOutputStream.write(outStream);//you can configure more things here
outStream.flush();
return;
}

8
2018-05-20 23:37



dalam template

<md-button class="md-fab md-mini md-warn md-ink-ripple" ng-click="export()" aria-label="Export">
<md-icon class="material-icons" alt="Export" title="Export" aria-label="Export">
    system_update_alt
</md-icon></md-button>

dalam pengontrol

     $scope.export = function(){ $window.location.href = $scope.export; };

0
2018-03-03 13:34



Saya tahu ini adalah posting lama tapi saya kesulitan mendapatkan solusi apa pun di stack exchange yang berfungsi untuk mengunduh otomatis dengan posting Angular.

Inilah solusi saya (Gabungan jquery / Angular / php):

PHP

    return array($filename,$url); 

Sudut Pandang

    <a target="_self" id="downloadpdf" href={{downloadurl}} download={{filename}} style="display: none"></a>

Kontrol Sudut

setelah respons diterima dengan url dan nama file:

     $scope.downloadurl=data[1];
     $scope.filename=data[0];

     setTimeout(function () {
                        $('#downloadpdf')[0].click();
                    }, 1000);  

Saya menempatkan ini pada penundaan 1 detik untuk memberikan waktu bagi nilai-nilai untuk mengisi karena kadang-kadang mengeksekusi terlalu cepat.

Semoga itu membantu!


-9
2018-02-14 22:24