2015-10-09 5 views
16

Ich habe Code geschrieben, der Angular $ http verwendet, um eine Datei herunterzuladen. Der Name der Datei ist nicht in der URL angegeben. Die URL enthält eine eindeutige Kennung für die Datei, die von außerhalb der Anwendung abgerufen wird.

Wenn $http.get(myUrl) aufgerufen wird, funktioniert alles gut; Die Datei wird abgerufen, und ich kann in meinem Callback-Handler auf sie zugreifen, aber ich kann nicht sehen, wie der Name der Datei abgerufen wird. Erfassung die rohe Reaktion mit Fiddler, sehe ich:

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 54 
Content-Type: application/octet-stream 
Server: Microsoft-IIS/8.5 
Access-Control-Allow-Origin: http://www.example.com/getFile/12345 
Access-Control-Allow-Credentials: true 
Content-Disposition: attachment; filename=testfile.txt 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Fri, 09 Oct 2015 20:25:49 GMT 

Lorem ipsum dolar sit amet! The contents of my file! 

Aus dem Vorstehenden ist es klar, dass der Server den Namen der Datei, in der „Content-Disposition“ sendet zurück, aber ich habe nicht gefunden sowieso um es innerhalb meines Angular Callbacks zu erreichen. Wie bekomme ich den Namen der Datei aus den Headern?

bearbeiten als Antwort unten zu beantworten: ich erwähnt habe, sollte vor, dass ich response.headers() schon versucht. Es gibt Object {content-type: "application/octet-stream", cache-control: "private"} zurück, also bekomme ich aus irgendeinem Grund immer noch keine Content-Disposition. response.headers('Content-Disposition') gibt null zurück.

+0

Wenn 'response.headers ('Content-Disposition') null zurückgibt ', ist eindeutig etwas nicht in Ordnung. Die Antwort von @andrew funktioniert einwandfrei – spankmaster79

+0

hast du eine Lösung gefunden? Ich habe genau das gleiche Problem: Fiddler zeigt deutlich eine korrekte Inhaltsdisposition header, aber keine der folgenden Lösungen funktioniert: response.headers ('Content-Disposition') gibt null – fikkatra

+0

Ich konnte es im Kontext der jeweiligen arbeiten Aufgabe, die ich gemacht habe, aber ich habe keine gute allgemeine Antwort. –

Antwort

5

Verwenden response.headers http-Antwort-Header erhalten:

$http.get(myUrl).then(function (response) { 
    // extract filename from response.headers('Content-Disposition') 
} 
+0

Ich habe das schon versucht. Ich hätte es vorher erwähnen sollen, also habe ich das an meine Frage angehängt. –

+3

In der Tat müssen Sie die Kopfzeile mit "Access-Control-Expose-Header: Content-Disposition" verfügbar machen. Dies setzt voraus, dass Sie die Kontrolle über die serverseitige Antwort haben ... –

+0

Ich habe Probleme, dies herauszufinden. Benötige ich die "Access-Control-Expose-Header" in der "Preflight" -Antwort oder die Antwort, die die eigentliche Datei enthält? –

4

Vielleicht haben Sie bereits Lösung finden, aber ich werde diese Antwort schreiben, wenn jemand anderes hat dieses Problem.

diese Parameter für den Erfolg Callback-Funktion hinzufügen aus dem $ http Anfrage:

$http.get(myUrl).success(function (data, status, headers, config) { 
     // extract filename from headers('Content-Disposition') 
    }); 
26

Es kann sich lohnen, dass, um zu erwähnen, den Dateinamen aus den HTTP-Header zu erhalten, Extrahieren des Content-Disposition Header ist nicht genug . Sie müssen immer noch die filename Eigenschaft von diesem Header-Wert erhalten.

Beispiel für zurückgegebenen Header-Wert: attachment; filename="myFileName.pdf".

Die folgende Funktion wird filename="myFileName.pdf" extrahieren, dann extrahieren "myFileName.pdf" und schließlich die zusätzlichen Anführungszeichen entfernen, um myFileName.pdf zu erhalten.

Sie können das Snippet unten verwenden:

function getFileNameFromHttpResponse(httpResponse) { 
     var contentDispositionHeader = httpResponse.headers('Content-Disposition'); 
     var result = contentDispositionHeader.split(';')[1].trim().split('=')[1]; 
     return result.replace(/"/g, ''); 
    } 
8

Wenn Sie CORS verwenden, müssen Sie die "Access-Control-Expose-Header", um die Response-Header auf Server-Seite hinzuzufügen. Beispiel: Access-Control-Expose-Headers: x-filename, x-something-else

+1

Sie teilweise wahr. Für CORS muss der Server den Header als 'Access-Control-Expose-Headers: Content-Disposition' senden. –

1

Wenn response.headers('Content-Disposition') null zurückgibt, verwenden Sie response.headers.**get**('Content-Disposition');.

Der Rest von @ Andrew Snippet funktioniert jetzt großartig.

0

ähnlich wie einige der oben genannten Antworten, aber eine grundlegende RegEx verwenden ist, wie ich es anstelle gelöst:

let fileName = parseFilenameFromContentDisposition(response.headers('Content-Disposition')); 

function parseFilenameFromContentDisposition(contentDisposition) { 
    if (!contentDisposition) return null; 
    let matches = /filename="(.*?)"/g.exec(contentDisposition); 

    return matches && matches.length > 1 ? matches[1] : null; 
} 
1

Web API: Ich fand, dass die folgende Zeile des Codes in die ExecuteAsync (...) Methode meiner IHttpActionResult Umsetzung gearbeitet (‚Antwort‘ die HttpResponseMessage zurückgegeben) wird:

response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition"); 

Angular: Ich habe die Dateinamen in Winkel zu lösen war dann in der Lage wie folgt (‚Antwort‘ ist die gelöstes Versprechen von $ http.get):

var contentDisposition = response.headers('Content-Disposition'); 
var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim(); 
Verwandte Themen