web-dev-qa-db-fra.com

Pourquoi envoyer un fichier est si difficile à utiliser angulaire?

Je dois envoyer un fichier (très gros fichier) à un serveur. J'étudie quelles options j'ai et comment le faire. J'utilise angular + express + nodejs.

Si j'utilise un formulaire simple, je pourrais attraper le fichier sur le serveur en utilisant multer sans problème. Est très simple. Le html est juste un formulaire, dans lequel je spécifie la cible, etc. et tout fonctionne. Le code nodejs est également très simple et direct.

Dès que j'essaie d'utiliser angulaire, tout devient incroyablement compliqué. Cela signifie que je dois utiliser une directive et que j'ai toujours des problèmes avec le serveur. Comme je l'ai dit, j'utilise multer, ce qui nécessite que les données soient "multipart/form-data", et j'obtiens du serveur "Erreur: Multipart: Boundary not found"

Il existe de nombreux modules pour charger des fichiers en angulaire. Ce qui montre que c'est un problème récurrent avec plus d'une solution. Maintenant, je ne veux pas poster de code parce que pour cela j'ai demandé à Stack Overflow . Ma question est plus subtile:

Pourquoi ce qui peut être fait avec une forme simple, devient si compliqué en angulaire? Je ne le pense pas mal. Je veux dire d'une manière "je veux comprendre".

19
cauchy

Angular est destiné aux applications à page unique, les formulaires sont envoyés à l'aide de AJAX pour éviter que la page ne soit rechargée. Pour envoyer des formulaires en plusieurs parties avec AJAX, votre navigateur doit prendre en charge FormData (IE10 +) : http://caniuse.com/#search=FormData

https://developer.mozilla.org/en-US/docs/Web/API/FormData

ngModel ne fonctionne pas avec l'entrée [type = "file"], vous devez donc créer votre propre directive. Votre propre directive doit être simple: en cas de modification, mettez à jour un objet File sur votre portée.

Lors de l'envoi de votre formulaire, créez un objet FormData et ajoutez-y vos fichiers à l'aide de FormData.set ou FormData.append. Vous pouvez envoyer votre FormData avec $http ou $resource, et vous comptez sur le navigateur pour définir le type de contenu et la limite.

var formData = new FormData();
formData.append('file', $scope.file);
$http.post('yourUrl', formData, {
   transformRequest: angular.identity,
   headers: {'Content-Type': undefined}
}).then(function () {
   // ...
});

angular.identity empêche Angular de faire quoi que ce soit sur nos données (comme les sérialiser).

Je recommande cet article: https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

22
Thomas Roch