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