web-dev-qa-db-fra.com

Comment obtenir le nom d'un fichier téléchargé avec Angular $ http?

J'ai écrit du code qui utilise Angular $ http pour télécharger un fichier. Le nom du fichier est not spécifié dans l'URL. L'URL contient un identifiant unique pour le fichier, qui est récupéré de l'extérieur de l'application.

Lorsque $http.get(myUrl) est appelé, tout fonctionne correctement. le fichier est récupéré et je peux y accéder dans mon gestionnaire de rappel, mais je ne vois pas comment obtenir le nom du fichier. En capturant la réponse brute avec Fiddler, je vois ceci:

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!

D'après ce qui précède, il est clair que le serveur renvoie le nom du fichier dans le "Contenu-Disposition", mais je n'ai pas encore trouvé comment y accéder dans mon rappel angulaire. Comment puis-je obtenir le nom du fichier à partir des en-têtes?

Modifier en réponse à la réponse ci-dessous: J'aurais dû mentionner auparavant que j'avais déjà essayé response.headers(). Il renvoie Object {content-type: "application/octet-stream", cache-control: "private"}, je ne reçois donc toujours pas Content-Disposition pour une raison quelconque. response.headers('Content-Disposition') renvoie null.

22

Il peut être intéressant de noter que pour extraire le nom de fichier à partir des en-têtes HTTP, l'extraction de l'en-tête Content-Disposition ne suffit pas. Vous devez toujours obtenir la propriété filename à partir de cette valeur d’en-tête.

Exemple de valeur d'en-tête renvoyée: attachment; filename="myFileName.pdf".

La fonction ci-dessous va extraire filename="myFileName.pdf", puis extraire "myFileName.pdf" et finalement supprimer les guillemets supplémentaires pour obtenir myFileName.pdf.

Vous pouvez utiliser l'extrait ci-dessous:

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

Si vous utilisez CORS, vous devez ajouter les "en-têtes de contrôle d'accès" aux en-têtes de réponse côté serveur. Par exemple: Access-Control-Expose-Headers: x-filename, x-something-else

12
Vladimir

API Web: j'ai constaté que l'ajout de la ligne de code suivante à la méthode ExecuteAsync (...) de mon implémentation IHttpActionResult fonctionnait ( 'réponse' est le HttpResponseMessage à renvoyer):

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

Angular: J'ai alors pu résoudre le nom du fichier angulaire de la manière suivante ( 'réponse' est la promesse résolue de $ http.get):

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

Utilisez response.headers pour obtenir les en-têtes de réponse http:

$http.get(myUrl).then(function (response) {
    // extract filename from response.headers('Content-Disposition')
} 
5
Michael P. Bazos

Si response.headers('Content-Disposition') renvoie null, utilisez response.headers.**get**('Content-Disposition');.

Le reste de l'extrait de @ andrew fonctionne maintenant très bien. 

4
andreisrob

Peut-être que vous trouvez déjà une solution, mais je posterai cette réponse si quelqu'un d'autre a ce problème.

Ajoutez ces paramètres dans la fonction de rappel de réussite à partir de la requête $ http:

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

Semblable à certaines des réponses ci-dessus, mais en utilisant un RegEx de base, voici comment je l'ai résolu à la place:

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;
}
3
Pat Migliaccio
success(function(data, status, headers, response,xhr) {
    console.log(headers('Content-Disposition'));
}
0
Bernard