Angularjs einfacher Datei-Download bewirkt, dass der Router umgeleitet wird

HTML:

 

Uploads erhalten einen eindeutigen Dateinamen, während der richtige Name in der database gespeichert wird. Ich möchte einen einfachen Datei-Download realisieren. Aber der obige Code leitet zu / wegen:

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

Ich habe es versucht

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

aber das öffnet nur die Datei in einem neuen Fenster.

Irgendwelche Ideen, wie man einen echten Download für jeden Dateityp ermöglicht?

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

In folgenden Fällen werden Links nicht neu geschrieben; Stattdessen lädt der Browser die gesamte Seite neu auf den ursprünglichen Link.

  • Links, die ein Zielelement enthalten Beispiel:
    link

  • Absolute Links, die auf eine andere Domain verweisen Beispiel:
    link

  • Links beginnend mit ‘/’, die zu einem anderen Basispfad führen, wenn die Basis definiert ist Beispiel:
    link

In Ihrem Fall sollten Sie also ein Zielattribut wie folgt hinzufügen …

  

Wir mussten auch eine Lösung entwickeln, die sogar mit APIs funktioniert, die eine Authentifizierung erfordern (siehe diesen Artikel ).

Mit AngularJS auf den Punkt gebracht, wie wir es gemacht haben:

Schritt 1: Erstellen Sie eine dedizierte Direktive

 // 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); }); }; }] }); 

Schritt 2: Erstellen Sie eine Vorlage

 Download 

Schritt 3: Verwenden Sie es

  

Dadurch wird eine blaue Schaltfläche angezeigt. Wenn Sie darauf klicken, wird eine PDF-Datei heruntergeladen (Vorsicht: das Backend muss die PDF-Datei in Base64-Kodierung liefern!) Und in die href-Datei eingefügt werden. Die Schaltfläche wird grün und der Text wird auf Speichern gesetzt . Der Benutzer kann erneut klicken und es wird ein Standarddownload -Dateidialog für die Datei my-awesome.pdf angezeigt .

In unserem Beispiel werden PDF-Dateien verwendet, aber anscheinend können Sie jedes Binärformat bereitstellen, sofern es korrekt codiert ist.

Wenn Sie eine erweiterte Richtlinie benötigen, empfehle ich die von mir implementierte Lösung, die in Internet Explorer 11, Chrome und FireFox korrekt getestet wurde.

Ich hoffe es wird hilfreich sein.

HTML:

  

RICHTLINIE:

 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('');//create a new  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  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'); } } }); } } }) 

IN KONTROLLER:

 $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=[]; }); }; 

IM DIENST:

 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 (am FRÜHLING):

 @RequestMapping(value = "/downloadURL/", method = RequestMethod.PUT) public void downloadExcel(HttpServletResponse response, @RequestBody Map 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; } 

in der Vorlage

   system_update_alt  

im Controller

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

Ich weiß, dass dies ein alter Post ist, aber ich hatte Probleme, eine Lösung für den Stapelaustausch zu finden, die für einen automatischen Download mit einem eckigen Post funktionierte.

Hier ist meine Lösung (Eine Mischung aus jQuery / Angular / PHP):

PHP

  return array($filename,$url); 

angularansicht

   

Eckiger Controller

Sobald die Antwort mit der URL und dem Dateinamen empfangen wurde:

  $scope.downloadurl=data[1]; $scope.filename=data[0]; setTimeout(function () { $('#downloadpdf')[0].click(); }, 1000); 

Ich habe dies auf eine Verzögerung von 1 Sekunde gesetzt, um den zu füllenden Werten Zeit zu geben, weil sie manchmal zu schnell ausgeführt wurde.

Ich hoffe es hilft!