2015-10-09 21 views
16

Ho scritto codice che utilizza $ http angolare per scaricare un file. Il nome del file è non specificato nell'URL. L'URL contiene un identificativo univoco per il file, che viene recuperato dall'esterno dell'applicazione.

Quando si chiama $http.get(myUrl), tutto funziona correttamente; il file viene recuperato e posso accedervi nel mio gestore di callback, ma non riesco a vedere come ottenere il nome del file. Catturare la risposta crudo con Fiddler, vedo questo:

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! 

Da quanto sopra, è chiaro che il server invia indietro il nome del file nel "Content-Disposition", ma non ho trovato comunque per accedervi entro il mio richiamo angolare. Come ottengo il nome del file dalle intestazioni?

Modifica in risposta alla risposta qui sotto: Avrei detto prima che ho già provato response.headers(). Restituisce Object {content-type: "application/octet-stream", cache-control: "private"}, quindi non trovo Content-Disposition per qualche motivo. response.headers('Content-Disposition') restituisce null.

+0

se 'response.headers ('Content-Disposition') restituisce null', c'è chiaramente qualcosa di sbagliato. La risposta di @andrew funziona perfettamente – spankmaster79

+0

hai trovato una soluzione? Ho esattamente lo stesso problema: Fiddler mostra chiaramente un'intestazione di disposizione del contenuto corretta, ma nessuna delle soluzioni seguenti funziona: response.headers ('Content-Disposition') restituisce null – fikkatra

+0

Sono stato in grado di farlo funzionare nel contesto del particolare compito che stavo facendo, ma non ho una buona risposta generale. –

risposta

5

Usa response.headers per ottenere intestazioni di risposta http:

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

Ho già provato questo. Avrei dovuto accennarlo prima, quindi ho aggiunto questo alla mia domanda. –

+3

In effetti, sarà necessario esporre l'intestazione con 'Access-Control-Expose-Headers: Content-Disposition'. Questo presuppone che tu abbia il controllo della risposta lato server ... –

+0

Ho problemi a capirlo. Ho bisogno di "Access-Control-Expose-Headers" sulla risposta "preflight" o sulla risposta che contiene il file attuale? –

4

Forse già trovare soluzione, ma mi post questa risposta se qualcun altro ha questo problema.

Aggiungere questi parametri nella funzione di successo di richiamata dalla richiesta $ http:

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

può valere la pena di ricordare che, al fine di ottenere il nome del file da intestazioni HTTP, estraendo l'intestazione Content-Disposition non è sufficiente . È ancora necessario ottenere la proprietà filename da questo valore di intestazione.

Esempio di valore intestazione restituito: attachment; filename="myFileName.pdf".

La funzione seguente estrae filename="myFileName.pdf", quindi estrae "myFileName.pdf" e infine rimuove le virgolette aggiuntive per ottenere myFileName.pdf.

È possibile utilizzare il frammento di seguito:

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

Se si utilizza CORS, è necessario aggiungere le "Access-Control-Expose-Headers" per le intestazioni di risposta sul lato server. Ad esempio: Access-Control-Expose-Headers: x-filename, x-something-else

+1

parzialmente vero. Per CORS, il server deve inviare l'intestazione come 'Access-Control-Expose-Headers: Content-Disposition'. –

1

Se response.headers('Content-Disposition') restituisce null, utilizzare response.headers.**get**('Content-Disposition');.

Il resto dello snippet di @ andrew ora funziona alla grande.

0

Simile ad alcune delle risposte di cui sopra, ma utilizzando un RegEx base è come ho risolto invece:

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: ho scoperto che aggiungendo la seguente riga di codice nel ExecuteAsync (...) Metodo di mia implementazione IHttpActionResult lavorato ('risposta' è la HttpResponseMessage essere restituito):

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

angolare: Mi è stato poi in grado di risolvere il nome del file in angolare come segue ('risposta' è la promessa risolta da $ http.get):

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