2016-12-04 4 views
0

So habe ich ein Problem, wenn ich versuchte, Datei von Server-Antwort zu speichern.Javascript speichern Datei von HTTP-Antwort (Web API HttpResponseMessage)

Wenn ich versuche, die Datei von URL in meinem Browser alle Arbeit herunterzuladen, aber wenn ich versuchte, Anfrage von der Clint Seite zu senden, wird die Datei gespeichert, aber in der Datei gibt es "[Object object]" und wenn es eine PDF ist Datei wird nicht geöffnet.

Die Anforderung muss einen zusätzlichen Header enthalten, der die Schlüssel-ID des Clients enthält.

Hier mein Server-Code:

 [HttpGet, IsAllowed(4,PageAction.Download)] 
    public HttpResponseMessage Download(string id) 
    { 
     var path = HttpContext.Current.Server.MapPath("~") + string.Format(@"Files\{0}.doc",id); 
     var stream = new FileStream(path, FileMode.Open); 
     HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     result.Content = new StreamContent(stream); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");    
     result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 
     result.Content.Headers.ContentDisposition.FileName = string.Format("{0}.doc", id); 
     return result; 
    } 

Und hier meine clint Code:

function get() { 
    var defer = $q.defer(); 

    $http.post('http://localhost:4704/api/file/download/1', { responseType: 'arrayBuffer' }).then(
     function (data, status, headers, config) { 
      var results = { 
       data: data, 
       headers: data.headers(), 
       status: data.status, 
       config: data.config 
      }; 
      defer.resolve(results); 

     }, function (data, status, headers, config) { 
      defer.reject(data); 
     }); 
    return defer.promise; 
} 


$scope.download = function() { 

    get().then(function (response) { 
     var octetStreamMime = 'application/octet-stream'; 
     var fileName = "Test.doc"; 
     var contentType = response.headers["content-type"] || octetStreamMime; 
     try { 
      var blob = new Blob([response.data], { type: contentType }); 
      if (window.navigator && window.navigator.msSaveOrOpenBlob) { 
       window.navigator.msSaveOrOpenBlob(blob, fileName); 
      } else { 
       var objectUrl = URL.createObjectURL(blob); 
       window.open(objectUrl); 
      } 
     } catch (exc) { 
      console.log("Save Blob method failed with the following exception."); 
      console.log(exc); 
     } 

    }, function (error) { 

    }); 

Darüber hinaus habe ich auch versucht, den folgenden Code:

$http.get("http://localhost:4704/api/file/download").then(function (res) { 
     var anchor = angular.element('<a/>'); 
     anchor.attr({ 
      href: 'data:attachment/doc;charset=utf-8,', 
      target: '_blank', 
      download: 'test.doc' 
     })[0].click(); 
    }) 
+0

wenn Sie versuchen, eine Datei herunterzuladen. Der Header muss ** content-type: multipart/form-data ** haben. Wenn Sie die PDF-Datei nicht richtig öffnen können, bedeutet dies, dass der Stream betroffen ist. also müssen Sie in den Konvertierungen herausfinden – Aravind

Antwort

0

Die Server-Code eindeutig binäre Daten in Antwort auf einen HTTP GET sendet vom Client aus. In diesem Fall muss der Client den XHR auf responseType: arraybuffer setzen.

Beispiel HTML

<button ng-click="fetch()">Get file</button> 

<a download="{{filename}}" xd-href="data"> 
    <button>SaveAs {{filename}}</button> 
</a> 

Die HTML erstellt zwei Schaltflächen. Durch Klicken auf die erste Schaltfläche wird die Datei vom Server abgerufen. Die zweite Schaltfläche speichert die Datei.

xd-href Richtlinie

app.directive("xdHref", function() { 
    return function linkFn (scope, elem, attrs) { 
    scope.$watch(attrs.xdHref, function(newVal) { 
     newVal && elem.attr("href", newVal); 
    }); 
    }; 
}); 

Die Richtlinie sieht den Umfang Eigentum des xd-href Attribut definiert und setzt das href Attribut auf den Wert dieses Bereichs Eigenschaft.

Regler

var url = "http://localhost:4704/api/file/download/1"; 
$scope.fetch = function() { 
    $http.get(url, {responseType: "arraybuffer"}) 
     .then (function (response) { 
     var disposition = response.headers("content-disposition"); 
     var filename = disposition.match(/filename="(\w*.\w*)"/)[1]; 
     $scope.filename = filename || "f.bin"; 
     $scope.data = new Blob([response.data]); 
    }).catch(function (error) { 
     console.log(error); 
     throw error; 
    }); 
}; 

Der Controller verwendet eine XHR GET-Methode die Datei extrahiert den Dateinamen aus dem Content-Disposition Header und erzeugt einen BLOB von den Antwortdaten zu holen. Er setzt das Attribut download des Tags <a> auf den Wert des Dateinamens und das Attribut href auf den Wert des Blobs. Wenn Sie auf <a> klicken, öffnet der Browser ein Speicherdialogfeld.

0

Wenn die Daten Im JSON-Format können Sie diese

verwenden
href: 'data:text/plain;charset=utf-8,' + JSON.stringify(data) 

oder Sie können dies auch Ihre Daten zu codieren verwenden, versuchen Sie diesen

href: 'data:text/plain;charset=utf-8,' + encodeURIComponent(data) 
+0

Danke für die Hilfe, aber es hat das Problem nicht gelöst ... –

Verwandte Themen