Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Accéder à des services web avec Mozilla en utilisant un proxy WSDL

Cette page est en cours de traduction, son contenu peut donc être incomplet ou contenir des parties en anglais. N'hésitez pas à participer à sa traduction à partir de Accessing_Web_Services_in_Mozilla_Using_WSDL_Proxying

Obsolète
Cette fonctionnalité est obsolète. Bien qu'encore supportée par des navigateurs, son utilisation est découragée pour tout nouveau projet. Évitez de l'utiliser.

Note concernant Firefox 3

Le support natif de WSDL et de SOAP a été enlevé de Mozilla 1.9/Firefox 3.

L'article sur le support de SOAP (Simple Object Access Protocol) dans les navigateurs basés sur Gecko expliquait comment accéder à des services Web en utilisant l'API de bas niveau SOAP de Mozilla. SOAP est un protocole de communication entre des objets distants, basé sur XML et souvent utilisé pour communiquer avec des services Web. SOAP nécessite de construire un message et son enveloppe au format attendu par le service, et de gérer la réponse pour en extraire les informations souhaitées.

Mozilla offre une interface JavaScript pour faciliter les communications via SOAP. Depuis Netscape 7.1/Mozilla 1.4, cette interface permet également l'utilisation de WSDL 1.1 (Web Services Description Language), une norme de description de services Web. Un fichier WSDL décrit les fonctionnalités d'un service et son interface, comme les fichiers d'en-tête en C ou IDL. Par ce biais, Gecko permet aux développeurs et aux développeuses d'appeler un service Web comme si c'était un objet JavaScript natif, en masquant complètement SOAP et XML. Par exemple, après avoir créé une instance "proxy" d'un service Web exposant son interface via WSDL, on peut appeler les méthodes du services comme des méthodes de l'objet JavaScript : proxy.getTranslation("en_fr", "Hello World") .

Cet article traite du support de WSDL dans les navigateurs basés sur Mozilla 1.7, des problèmes d'appels inter-domaines et du nouveau modèle de sécurité proposé par Netscape pour permettre aux services Web de déterminer si un client peut accéder au service depuis n'importe quel domaine ou uniquement depuis certains.

Il se base sur le service Web Babelfish fournis par XMethods, qui a été le premier site à implémenter le nouveau modèle de sécurité des services Web de Gecko, modèle qui permet aux navigateurs basés sur Gecko d'accéder à des services d'autres domaines.


Créer un proxy WSDL

Un proxy de service Web peut être créé en JavaScript en instanciant un objet de la classe WebServiceProxyFactory. Le fichier WSDL est chargé via l'appel de la méthode createProxyAsync de la classe WebServiceProxyFactory.

Le prototype de la méthode createProxyAsync est :

void createProxyAsync (String wsdlURL, String portname, String qualifier, boolean isAsync, WebServiceProxyCreationListener listener)

Elle attend 5 paramètres :

  1. L'emplacement du fichier WSDL. Par exemple pour Babelfish : https://www.xmethods.net/sd/2001/BabelFishService.wsdl .
  2. Le nom du port (en WSDL, un port correspond à une méthode du service). Ce nom fait parti de la description du service dans le fichier WSDL (cf la Figure 1).
  3. Le troisième paramètre est optionnel, il n'est utilisé que lors de l'appel de la méthode via XPCOM. On l'ignorera ici.
  4. Un booléen indiquant si l'appel est synchrone ou asynchrone. Netscape 7.1/Mozilla 1.4 ne permet pas de créer des proxies synchrones. Il faudra donc toujours positionner ce paramètre à true et fournir une procédure de rappel.
  5. Le dernier paramètre est la procédure de rappel qui sera appelée quand le proxy sera complètement initialisé. Pour plus de détails, lire la section suivante.

JavaScript :

var factory = new WebServiceProxyFactory();
factory.createProxyAsync("https://www.xmethods.net/sd/2001/BabelFishService.wsdl", "BabelFishPort", "", true, aCreationListener);    


WSDL :

<?xml version="1.0"?>
<definitions name="BabelFishService" ...>
  ...
  <service name="BabelFishService">
    <documentation>Traduit des textes jusqu'à 5 Ko entre plusieurs langages.</documentation>

    <port name="BabelFishPort" binding="tns:BabelFishBinding">
      <soap:address location="https://services.xmethods.net:80/perl/soaplite.cgi"/>
    <port>
  </service>
</definitions>

Figure 1. Instancier et initialiser un proxy de service Web.

edited by sebastian gurin where the argument's semantics are:

wsdlURL
The URL of the WSDL service description. This description will be loaded and used as the basis for the service proxy.
portname
The name of the port of the service that this service proxy represents. Currently the port must represent a SOAP binding.
qualifier
The user-specified qualifier is incorporated into the names of XPCOM interfaces created for the service proxy. For C++ callers, this qualifier should be the same one used in creating the IDL used at compile time. Script callers need not specify a qualifier.
isAsync
If PR_TRUE, the method signatures of the service proxy represent an asynchronous calling convention. A callback instance must be registered with the proxy. A method call to a web service is only completed when the corresponding callback method is invoked. If PR_FALSE, the method signatures of the service proxy represent a synchronous callling convention. A method call to a web service is completed when the method call to the proxy returns.
listener
The callback instance which will be invoked when the proxy is completely initialized.

You can also use the simpler WebServiceProxyFactory::createProxy(wsdlURL, portname, qualifier,isAsync) method for create a web service proxy. The API description of WebServiceProxyFactory can be found here here

La procédure de rappel

Le dernier paramètre de createProxyAsync est un « listener » de création (une procédure qui « écoute » et attend des évènements). Il est appelé quand le proxy a été créé avec succès, en cas d'erreur lors de cette création et à chaque appel d'une méthode du proxy.

Le listener de création est un objet de classe nsIWebServiceProxyCreationListener implémentant plusieurs méthodes :

  • une fonction onLoad appelée après l'initialisation du proxy et signifiant que les méthodes du proxy sont disponibles. Le proxy lui est passé en paramètre.
  • une fonction onError appelée en cas d'erreur à la génération du proxy ou lors de l'appel d'une de ses méthodes. Elle reçoit alors l'erreur en paramètre.


L'appel des méthodes du proxy est asynchrone. Le listener de création gère les retours (« callback ») à chaque appel de méthode. Ces retours utilisent un shéma de nommage spécifique : {nom_de_la_méthode}Callback. Le service Web de BabelFish ne fournit qu'une seule méthode : BabelFish (repérée par la balise operation dans le WSDL), la fonction de rappel sera donc nommée BabelFishCallback. La méthode BabelFish attend en entrée une BabelFishRequest composée de deux paramètres et renvoie la valeur traduite sous forme de chaîne de caractère. La figure 2 contient la partie du fichier WSDL décrivant cette méthode :

<message name="BabelFishRequest">
  <part name="translationmode" type="xsd:string"/>
  <part name="sourcedata" type="xsd:string"/>
</message>
<message name="BabelFishResponse">
  <part name="return" type="xsd:string"/>
</message>
<portType name="BabelFishPortType">
  <operation <span class="color1">name="BabelFish"<span>>
    <input message="tns:BabelFishRequest"/>
    <output message="tns:BabelFishResponse"/>
  </operation>
</portType>

Figure 2. Description de la méthode dans le fichier WSDL.

JavaScript :

var listener = {
  // appelée une fois le proxy instancié
  onLoad: function (aProxy) 
  {
    gProxy = aProxy;
    gProxy.setListener(listener);
    requestTranslation(aValue);
  },
  // appelée en cas d'erreur
  onError: function (aError) 
  {
    alert("Une erreur est survenue lors du traitement du fichier WSDL : " + aError);
  },
  // dans Mozilla 1.4, le nom de la procédure de retour est codé en dur à {nom_de_la_méthode}Callback in 1.4beta
  BabelFishCallback  : function (aResult) 
  {
    alert(aResult)
  }
};
function requestTranslation(aValue){
  if (gProxy) {
    gProxy.BabelFish("en_fr", aValue);
  } else {
    alert("Erreur à l'initialisation du proxy");
  }
}

Figure 3. Gestion de la fonction de retour.

Exemple

On utilise ci-dessous utilise le code précédent pour créer un exemple entièrement fonctionnel d'appel du service Web BabelFish pour traduire une chaîne saisie par l'utilisateur.

L'interface utilisateur est un formulaire avec deux listes déroulantes et un champ pour saisir le texte à traduire. La première liste déroulante (id="lang_from") permet de choisir la langue du mot à traduire, la seconde (id="lang_to") la langue dans laquelle le traduire. Un bouton appelle la fonction initTranslation. Celle-ci vérifie que les langues d'origine et de destination sont différentes et, si c'est le cas, appelle la fonction Translate. Le service Web Babel Fish attend deux arguments : une chaîne au format langueSource_langueDestination et la chaîne à traduire.

function initTranslation(){
  var fromLang = document.getElementById('lang_from').value;
  var toLang = document.getElementById('lang_to').value;

  if (fromLang != toLang)
    Translate(fromLang+'_'+toLang, document.getElementById('inputValue').value);
  else
    alert("Traduire d'une langue vers elle-même est de peu d'utilité :-) ");
}

Figure 4. Initier la traduction

C'est la fonction Translate qui effectue l'appel du service Web. Elle teste si un objet « proxy » a déjà été créé en regardant si la variable globale gProxy est à null ou non. Si l'objet n'existe pas encore, la fonction crée un listener et l'affecte à une variable nommée listener. Elle appelle ensuite la fonction createProxy avec ce listener. Si le proxy avait déjà été créé, elle appelle la fonction requestTranslation.

var gProxy = null;


function Translate(aLangToFrom, aString){
  if (!gProxy) {
    var listener = {
      // gets called once the proxy has been instantiated
      onLoad: function (aProxy)
      {
        gProxy = aProxy;
        gProxy.setListener(listener);
        requestTranslation(aLangToFrom, aString);
      },
      // gets called if an error occurs
      onError: function (aError)
      {
        alert("An error has occured: " + aError);
      },
      // callback function is hardcoded to {methodname}Callback
      BabelFishCallback  : function (aResult)
      {
        document.getElementById("results").innerHTML = aResult;
      }
    };
    <span class="color1">createProxy(listener)<span>;
  } else {
    <span class="color2">requestTranslation(aLangToFrom, aString)<span>;
  }
}


function <span class="color1">createProxy<span>(aCreationListener){
  try {
    var factory = new WebServiceProxyFactory();
    factory.createProxyAsync("https://www.xmethods.net/sd/2001/BabelFishService.wsdl", "BabelFishPort", "", true, aCreationListener);
  } catch (ex) {
    alert("Failed creating the proxy: "+ ex);
  }
}


function <span class="color2">requestTranslation<span>(aLangToFrom, aString){
  if (gProxy) {
    gProxy.BabelFish(aLangToFrom, aString);
  } else {
    alert("Error: Proxy hasn't been set up correctly!");
  }
}

Figure 5. Création du proxy

La fonction createProxy est exécutée à la première demande de traduction. Elle instancie un objet de classe WebServiceProxyFactory et crée un nouveau proxy via la méthode createProxyAsync, à laquelle est passé le listener de création. Une fois le proxy créé, la méthode onLoad du listener est appelée. Elle effecte le proxy à la variable globale gProxy, enregistre le listener comme listener du proxy et appelle requestTranslation puisque le proxy est prêt à l'emploi.

La fonction requestTranslation appelle à son tour la méthode BabelFish du proxy pour effectuer l'appel du service Web. En cas de succès de l'appel, la méthode BabelFishCallback du listener est exécutée, elle affiche la traduction dans un div. En cas d'erreur de l'appel (par exemple si une erreur SOAP est retournée), la méthode onError du listener est appelée.

On peut tester le formulaire de traduction (Netscape 7.1/Mozilla 1.4 ou versions supérieures).

Le modèle de sécurité

Un des problèmes posés par l'implémentation d'appel à des services Web dans le navigateur est la question du modèle de sécurité multi-domaine. Une limitation de JavaScript impose qu'il ne peut charger de données que depuis le même domaine que celui du serveur où le script est hébergé. Par exemple Netscape.com ne peut récupérer de données via l'appel XMLHTTPRequest que de services dans le domaine netscape.com et non de toto.com. Un autre modèle de sécurité est donc nécessaire pour permettre à un site de se connecter à un service Web distant.

Netscape a proposé au W3C un modèle de sécurité dans lequel le fournisseur d'un service Web détermine si celui-ci est accessible par tout le monde, uniquement depuis certains domaines ou n'est pas accessible depuis Internet. Il faut pour cela placer un fichier XML à la racine du serveur hébergeant le service. Dans le cas de XMethods qui fournit Babelfish, le fichier en question est à cette adresse https://services.xmethods.net/web-scripts-access.xml et autorise l'appel du service depuis n'importe quel domaine, ce qui permet à l'exemple de cet article d'effectuer un appel sur un autre serveur. On trouvera plus d'informations sur ce modèle de sécurité à cette adresse : https://lxr.mozilla.org/mozilla/sourc...ity_Model.html.


Categories

Interwiki Language Links

Étiquettes et contributeurs liés au document

Étiquettes : 
 Contributeurs à cette page : Fredchat, Chbok, Mozinet, Clochix
 Dernière mise à jour par : Fredchat,