2015-10-09 17 views
16

Napisałem kod, który używa Angular $ http do pobrania pliku. Nazwa pliku to , a nie określona w adresie URL. Adres URL zawiera unikalny identyfikator pliku, który jest pobierany spoza aplikacji.

Po wywołaniu $http.get(myUrl) wszystko działa poprawnie; plik jest pobierany i mogę uzyskać do niego dostęp w moim programie obsługi wywołania zwrotnego, ale nie widzę sposobu pobrania nazwy pliku. Przechwytywanie surową odpowiedź z Skrzypek, widzę to:

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! 

Z powyższego jasno wynika, że ​​serwer wysyła z powrotem nazwę pliku w polu „Content-Disposition”, ale nie znalazłem w każdym razie, aby uzyskać do niego dostęp w ramach mojego angularnego wywołania zwrotnego. Jak uzyskać nazwę pliku z nagłówków?

Edycja w odpowiedzi odpowiedzieć poniżej: powinny Wspomniałem wcześniej, że już próbował response.headers(). Zwraca ona Object {content-type: "application/octet-stream", cache-control: "private"}, więc nadal nie otrzymuję dyspozycji zawartości z jakiegoś powodu. response.headers('Content-Disposition') zwraca null.

+0

jeśli 'response.headers ('Content-Disposition') zwróci wartość null" jest wyraźnie coś nie tak. Odpowiedź od @andrew działa idealnie – spankmaster79

+0

znalazłeś rozwiązanie? Mam dokładnie ten sam problem: Fiddler wyraźnie pokazuje poprawny nagłówek zawartości, ale żadne z poniższych rozwiązań nie działa: response.headers ("Content-Disposition") zwraca null – fikkatra

+0

Udało mi się sprawić, by działało w kontekście konkretnego Zadanie, które robiłem, ale nie mam dobrej ogólnej odpowiedzi. –

Odpowiedz

5

Zastosowanie response.headers uzyskać nagłówki odpowiedzi http:

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

Już wypróbowałem to. Powinienem był o tym wspomnieć wcześniej, więc dołączyłem to do mojego pytania. –

+3

Rzeczywiście, będziesz musiał odsłonić nagłówek za pomocą 'Access-Control-Expose-Headers: Content-Disposition'. Zakłada to, że masz kontrolę nad odpowiedzią po stronie serwera ... –

+0

Mam problem z ustaleniem tego. Czy potrzebuję nagłówków "Kontrola dostępu-Ujawnianie" w odpowiedzi "preflight" lub odpowiedzi zawierającej rzeczywisty plik? –

4

Może już znaleźć rozwiązanie, ale będę pisać tę odpowiedź, jeśli ktoś ma ten problem.

Dodaj te parametry w funkcji sukces wywołania zwrotnego z żądania $ http:

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

Warto może wspomnieć, że w celu uzyskania nazwy pliku z nagłówków HTTP, wydobywania nagłówek Content-Disposition nie wystarczy . Nadal musisz uzyskać właściwość filename z tej wartości nagłówka.

Przykład zwróconej wartości nagłówka: attachment; filename="myFileName.pdf".

Poniższa funkcja wyodrębni filename="myFileName.pdf", a następnie wyodrębni "myFileName.pdf", a na końcu usunie dodatkowe cytaty, aby uzyskać myFileName.pdf.

Można użyć poniższego fragmentu:

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

Jeśli używasz CORS, trzeba dodać "Access-Control-Expose-headers" do nagłówków odpowiedzi na stronie serwera. Na przykład: Access-Control-Expose-Headers: x-filename, x-something-else

+1

Po części prawda. W przypadku CORS serwer musi wysyłać nagłówek jako 'Access-Control-Expose-Headers: Content-Disposition'. –

1

Jeśli response.headers('Content-Disposition') zwróci wartość null, użyj response.headers.**get**('Content-Disposition');.

Reszta fragmentu @ andrew jest teraz świetna.

0

podobne do niektórych z powyższych odpowiedzi, ale stosując podstawową RegEx jak ja rozwiązałem zamiast:

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: Okazało się, że dodanie następującej linii kodu do ExecuteAsync (...) Metoda mojego realizacji IHttpActionResult pracował („odpowiedź” jest HttpResponseMessage zostać zwrócone):

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

kątowa: Byłem wtedy w stanie rozwiązać nazwę pliku w kanciasty następująco („odpowiedź” jest rozwiązana obietnica z $ http.get):

var contentDisposition = response.headers('Content-Disposition'); 
var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim(); 
Powiązane problemy