envoyer un fichier avec une API "rest"

L'auteur de ce sujet a trouvé une solution à son problème.
Staff
Auteur du sujet

BOnjour à tous,

j'utilise actuellement javascript et jquery pour gérer la soumission d'un formulaire en AJAX + JSON et l'affichage asynchrone des résultats avec un websocket.

Le truc c'est qu'en plus des données statiques, je voudrais ajouter l'upload d'un (ou plusieurs?) fichier.

Actuellement, je suis obligé de passer par la soumission "normale" du formulaire. Le problème principal étant que dans certains traitement, je suis obligé de passer par du multiprocess.

C'est un problème car soumettre "normallement" le formulaire recharge la page. Et qui dit "page rechargée" dit "web socket déconnectée". Mais la déconnexion est… asynchrone. Et de même que la reconnexion. Du coup je n'ai aucune garantie que le process de traitement notifiera la nouvelle websocket (en fait il ne le fait presque jamais).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    $(function(){
        $("#config-charge").submit(function(e){

            var custom = $("#field-custom")[0].checked;
            if( custom && document.getElementById("corpus_file").files){
                return true;
            }
            var data = {};
            try{
                call_ajax(resolve_data(data));
                $(".errored-field").each(function(){
                    $(this).removeClass("errored-field");
                });
            }
            catch(Error){
                if(data.errors)  {
                    $("#error-list").html('');
                    for(var i=0; i< data.errors.length; i++){
                        $("#error-list").append($("p").text(data.errors[i].message));
                        data.errors[i].field.addClass("errored-field");
                    }
                }
            }
            e.stopPropagation();
            return false;
        });
    });

gestion de la soumission

Comme mon outil est à destination de personnes qui ont tous (à 100%, c'est dans les specs) javascript activé, les websockets de supportés etc. je voudrais pouvoir envoyer le fichier par javascript.

Il fut un temps où j'avais essayé mais j'avais sans cesse des erreurs en utilisant les objets FormData.

Auriez-vous connaissance d'un moyen simple (ou d'un plugin Jquery) qui permette de répondre à mon besoin? Ou bien d'une autre manière de concevoir le code?

+0 -0

En HTML 5 ça se fait bien je pense.

FileApi + websockets.

La file api te permet de récupérer des chunks, que tu envoies en binary frames dans la websocket.

http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/ peut aider ptet'.

En gros je partirais sur : new FileReader(...).readAsArrayBuffer(...), et websocket.send(buffer)

J'aurais tendance à dire que ça se fait bien mais comme j'ai jamais essayé vraiment, je me retiens.

En espérant que ça t'aiguille.

Édité par Javier

Happiness is a warm puppy

+0 -0
Staff
Auteur du sujet

ça me donne une idée mais du coup va falloir que je change complètement la manière de faire.

Notons que j'ai aussi trouvé un plugin jquery qui pourrait m'aider : https://github.com/blueimp/jQuery-File-Upload/wiki/API

mais dans un cas comme dans l'autre, cela signifie qu'il faut que je télécharge le fichier avant de valider le formulaire. Je vous en dis plus quand j'aurai fait des tests du coup.

+0 -0

Ah, OK. Donc si je comprends bien, il va te falloir dissocier l'upload du fichier de l'envoi du formulaire pour que ce soit asynchrone, et réassocier une fois que les deux éléments ont été soumis ?

Édité par Ymox

Evitez qu'on vous dise de les lire : FAQ PHP et Symfony 2Tutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0

Dans ce cas, est-ce que tu peux imaginer d'avoir un "ID de soumission" qui te permette de lier toutes celles effectuées de manière asynchrone ?

Dans le formulaire principal (qui est très probablement le dernier à être soumis, mais un des premiers à être traité), tu mets le nombre de soumissions de fichiers que tu as enregistré, et avec chaque fichier, tu envoies l'ID. Ainsi, quand un fichier est totalement uploadé, tu regardes si c'est le dernier et dans ce cas tu relies les informations. Si cet ID est celui de ton formulaire, alors avec une simple jointure tu devrais avoir ce qu'il te faut, je dirais.

Édité par Ymox

Evitez qu'on vous dise de les lire : FAQ PHP et Symfony 2Tutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0

Mais bon, ça ne te règle pas le souci de déconnexion quand le formulaire est soumis, si je ne m'abuse…

Tu pourrais faire comme Google et ses téléchargements, qui s'ouvrent dans un popup avec un iframe à l'intérieur ? Pas super pratique, mais en même temps, c'est un peu la seule manière que je vois pour conserver les connexions tout en permettant à la "page de référence" d'être rechargée.

Evitez qu'on vous dise de les lire : FAQ PHP et Symfony 2Tutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0

De toute façon qui dit websocket ouverte sur une page, dit, quasi-systématiquement protocole de contrôle entre client et serveur. Aussi basique soit-il.

Les cas où y'a une seule socket par page (parce que c'est moyen d'en ouvrir 74000) suffit à faire un truc et un seul, unitaire, atomique, ça n'existe que dans les articles de blog.

Dans la pratique j'ai quasiment toujours eu besoin de définir ne serait-ce qu'un embryon de protocole entre client et serveur quand tu mets en place une communication par ws.

Un avantage, dans ton cas, c'est que (on retrouve du jargon de protocoles réseaux) le plan contrôle et le plan données sont des types de frames différents. (texte / binaire). Du coup côté serveur c'est plus sympa/élégant à écrire : toutes les frames text sont du "signaling" (nouveau fichier, fin fichier, …) toutes les frames binaires sont des données. Un handler pour chaque type de frame.

Happiness is a warm puppy

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte