/* classe API */ function APIClass(target, subdir){ this.target = target; this.subdir = subdir || ''; } APIClass.prototype = { xhr: [], // tableau d'objets pour les requêtes ajax buffer: null, // Contiendra le buffer pour debugger si erreur de parsage optionalParams: [], // Contiendra les paramètres que l'on veut passer au scope de @pHandler /* retourne l'url complète de la cible * * */ getTarget: function(){ var trimedTarget = '/' + this.target.replace(/ /g, '_').replace(/\//g, ' ').trim().replace(/ /g, '/') + '/'; var trimedSubdir = this.subdir.replace(/ /g, '_').replace(/\//g, ' ').trim().replace(/ /g, '/'); return trimedSubdir ? '/' + trimedSubdir + trimedTarget : trimedTarget; }, /* transaction avec le serveur (http://host/api/) * * @param pRequest l'objet passé en POST (attribut->postfield) à http://host/api/ * @param pHandler fonction qui s'éxécutera lors de la réponse (1 argument -> réponse) * @param pToken Optionnel, token d'auth pour l'api * @param pParams Optionnels, liste d'arguments à passer au scope de @pHandler * * @return answer l'objet retourné par http://host/api/ via pHandler (1er argument) * *************************************************************************************************** * * @usecase * 1. var answerObject = sendRequest( * 2. { var1: "exemple", var2: 198294 }, * 3. function(rep){ alert(rep); } * 4. ); * @explain * 1. on appelle la fonction <=> on créé la requête * 2. on passe l'objet qui sera envoyé * 3. on passe une fonction qui utilise un argument (sera la réponse de http://host/api/) (sous forme d'objet) * */ send: function(pRequest, pHandler, pToken){ // Si le chemin de delegation n'est pas renseigne, on renvoie une erreur if( !pRequest.hasOwnProperty('path') ) pHandler({ModuleError:4}); // on efface les requêtes qui sont terminées (toutes celles de this.xhr) for( var i = 0 ; i < this.xhr.length ; i++ ) if( this.xhr[i].readyState == 4 ) // si terminée this.xhr.splice(i, 1); // on créé une nouvelle entrée this.xhr.push(null); i = this.xhr.length-1; // Gestion des paramètres optionnels à passer au scope de @pHandler this.optionalParams[i] = []; if( arguments.length > 3 ) for( var arg = 3 ; arg < arguments.length ; arg++ ) this.optionalParams[i].push( arguments[arg] ); // création de l'objet AJAX if(window.XMLHttpRequest) // IE7+, Firefox, Chrome, Opera, Safari this.xhr[i] = new XMLHttpRequest(); else // IE5, IE6 this.xhr[i] = new ActiveXObject('Microsoft.XMLHttpRequest'); var ptrAPI = this; console.log('api request', pRequest); this.xhr[i].onreadystatechange = function(){ if( ptrAPI.xhr[i].readyState == 4 ){ // si la requête est terminée ptrAPI.buffer = ptrAPI.xhr[i].responseText; /* DEBUG : affiche la réponse BRUTE de http://host/api/ */ // console.log('http://host/api/ => '+ptrAPI.xhr[i].responseText); console.log('api response', JSON.parse(ptrAPI.xhr[i].responseText) ); /* si success de requête */ if( [0,200].indexOf(ptrAPI.xhr[i].status) > -1 ){ // si fichier existe et reçu try{ pHandler( JSON.parse(ptrAPI.xhr[i].responseText), ptrAPI.optionalParams[i]); } // si on peut parser, on envoie catch(e){ pHandler({ModuleError:-1, ErrorDescription:'Erreur au niveau de api.js'}, ptrAPI.optionalParams[i]); console.warn(e); } // sinon on envoie obj.request = 'corrupted' } /* sinon retourne obj.request = 'unreachable' */ else pHandler({ModuleError:3}); } }; // on créé un formulaire POST (virtuel) var form = new FormData(); // On ajoute tous les attributs en POST for( var key in pRequest ) // On envoie le 'path' tel quel if( key == 'path' ) form.append(key, pRequest[key]); // On envoie un fichier tel quel else if( pRequest[key] instanceof File ) form.append(key, pRequest[key]); // On envoie le reste en JSON else form.append(key, JSON.stringify(pRequest[key])); this.xhr[i].open('POST', this.getTarget(), true); // Gestion du token optionnel pToken && this.xhr[i].setRequestHeader('Authorization', 'Digest '+pToken); // Header pour dire que c'est AJAX this.xhr[i].setRequestHeader('X-Requested-With', 'XMLHttpRequest'); this.xhr[i].send( form ); } };