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.

SOAP in Gecko-based Browsers

廃止

Firefox 3 における注記

WSDL および SOAP のネイティブなサポートは Mozilla 1.9/Firefox 3 から削除されました。

 

この記事は、最近の Gecko ベースのブラウザ (しかし、 Firefox 3 では SOAP のサポートが外されています) で SOAP と JavaScript を使い、Web サービスにアクセスする方法について書かれています。

導入

Simple Object Access Protocol (SOAP) は、Web サービスの元になっています。SOAP は、XML を基にしたプロトコルでWeb サービスの互換性と情報伝達に使われます。Mozilla 1.0 (Netscape 7.0x がビルドされた) と Firefox は、現在では JavaScript を通して低レベルの SOAP 実装を使用する Web サービスと直接通信することができます。

SOAP の呼び出しを確立するための Gecko の JavaScript インタフェースは、いくつかの特別なJavaScript オブジェクトを使って SOAP envelope を作成する低レベル API です。 この記事は、基本的な SOAP 操作を担当しています。;Gecko での低レベル SOAP API の詳細はここにあります。

Web サービスと通信する JavaScript は、ドメインを超えることによる他のスクリプトと同じセキュリティポリシーの条件に制限を受けます。それ故に、JavaScript が動いているサーバ以外の Web サービスにアクセスすることは、クロスドメインポリシーに違反します。この記事には、テスト目的で一時的にこれをどのように回避するかが書かれています。

SOAP 呼び出しの設定

最も基本的なオブジェクトは、SOAPCallです。SOAP 呼び出しの開始と起動に使用します。

Figure 1 : 基本的な設定と SOAP 呼び出しの起動

var mySOAPCall = new SOAPCall();
mySOAPCall.transportURI = "http-based service URI"

var parameters = new Array();
mySOAPCall.encode(SOAPCall.VERSION_1_1,
                  // method
                  "method", "namespaceURI",
                  // header block
                  0, null,
                  // parameter
                  parameters.length, parameters);

var response = mySOAPCall.invoke();

SOAPCalltransportURI と呼ばれているメンバーを持っています。それは、SOAP 呼び出しを送る先の URI を指定します。encode() メソッドは、Web サービスで呼び出すメソッド名、名前空間の URI、通過させる SOAP パラメータの数、全てのパラメータを含んだ SOAP パラメータ配列を必要とします。これらの全てのパレメータは、例の段落で書かれている Web サービスの WSDL ファイルで見つけることが出来ます。

SOAP パラメータは、SOAPParameterオブジェクトを使って作られます。Web サービスで送られる名前/値の組です。

Figure 2 : SOAP パラメータを作る

var param = new SOAPParameter();
param.name = "translationmode";
param.value = "en_fr";

応答のハンドリング

一度 invoke() が呼び出されると、Gecko は SOAP envelope を作り、指定された URI に送信されます。 その呼び出しは同期されていて、応答は、invoke() の戻り値になります。

Figure 3 : 応答のハンドリング

var returnObject = mySOAPCall.invoke();

if(returnObject.fault){
  alert("An error occured: " + returnObject.fault.faultString);
} else {
  var response = new Array();
  response = returnObject.getParameters(false, {});
  alert("Return value: " + response[0].value);
}

invoke() の戻り値は保存され、fault メンバーでチェックされました。もし、fault が存在したら、Web サービスでエラーが起きています。そして、エラーメッセージは、fault.faultString に保存されています。もし、fault が無ければ、SOAP パラメータの応答のオブジェクトを取り出すために getParameters() を呼びます。

ここの例では、既に存在している Web サービス、xmethods.net で提供されている Babelfish を利用します。Babelfish Web サービスは、いくつかの言語間の翻訳を許しています。それは、2 つのパラメータをとります: "元の言語_結果の言語"の書式の文字列と他の言語へ変換する文字列。Babelfish Web サービスの WSDL ファイルは、ここにあり、Web サービスを呼ぶための低レベルの SOAP 呼び出しを設定するのに必要な情報を含んでいます。

初めの段階は、Web サービスの位置を解決することです。SOAPCalltransportURI メンバーの値です。これは、WSDL のservice 要素、特に、soap:addresslocation 属性に見つけることが出来ます。

Figure 4 : WSDL から Web サービスの場所を特定する

WSDL:
  <service name="BabelFishService">
    <documentation>
      Translates text of up to 5k in length, between a variety of languages.
    </documentation>
    <port name="BabelFishPort" binding="tns:BabelFishBinding">
      <soap:address location="https://services.xmethods.net:80/perl/soaplite.cgi"/>
    </port>
  <service>

JavaScript:
  var babelFishCall = new SOAPCall();
  babelFishCall.transportURI = "https://services.xmethods.net:80/perl/soaplite.cgi";
  ...

次のステップは、もっと複雑です。:Web サービスが送信されることを期待しているパラメータを正確に形作ることです。 Babelfish Web サービスには、たった1つのメソッド "BabelFish" があります。これは、WSDL の中のportType 要素の子要素の operation に書かれています。WSDL の operation 毎に 2 つの子要素があります。:型の情報を含んだinputとoutput要素です。型は、message 要素で定義されています。型には 2 つあり: BabelFishRequestは、WebService に何を渡すかを表しています。そして、BabelFishResponse は、返ってくる型を表しています。


BableFishは、2 つのパラメータが operation に含まれていることを期待しています: translationmodesourcedata

Figure 5 の例では、"I am" を英語からフランス語に翻訳します。

Figure 5 : 必要なパラメータを設定する

WSDL:
  <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 name="BabelFish">
      <input message="tns:BabelFishRequest"/>
      <output message="tns:BabelFishResponse"/>
    </operation>
  </portType>
 
JavaScript: 
  // SOAP parameters
  var param1 = new SOAPParameter();
  param1.value = "en_fr";
  param1.name = "translationmode";
 
  var param2 = new SOAPParameter();
  param2.value = "I am";
 
  param2.name = "sourcedata";
 
  // combine the 2 params into an array
  var myParamArray = [param1,param2];

次に、SOAPCall オブジェクトの設定と呼び出しをする時です。"BabelFish" は、Web サービスの例として使って欲しいメソッドです。次のパラメータは、BabelFish のメソッドに Web サービスで渡されることが期待されている名前空間です。 これは、WSDL の binding 要素に見つけることが出来ます。binding 要素は、BabelFish メソッドのために operation を子供に持っています。名前空間の必要性は、input 要素の中の soap:body の属性の namespace の値です。

Figure 6 : エンコードされたメソッドを設定する

WSDL:
  <binding name="BabelFishBinding" type="tns:BabelFishPortType">
    <soap:binding style="rpc" transport="https://schemas.xmlsoap.org/soap/http"/>
    <operation name="BabelFish">
      <soap:operation soapAction="urn:xmethodsBabelFish#BabelFish"/>
      <input>
        <soap:body use="encoded" namespace="urn:xmethodsBabelFish"
                   encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/>
      </input>
      ...
    </operation>
  </binding>
 
JavaScript:          
  babelFishCall.encode(0, "BabelFish", "urn:xmethodsBabelFish", 0, null, myParamArray.length, myParamArray);

  var translation = babelFishCall.invoke();

Figure 5 で見たように、BabelFish メソッド ("BabelFishResponse") の応答は、名前を持った 1 つのパラメータを持っています。

エラーが返ってきていないのを確認した後、返ってきたオブジェクトの getParameters() メソッドは、SOAPResponse 配列を取り出すのに使われます。たった 1 つのパラメータが返ってくるのが期待されます。-- 解釈されたテキスト -- alert() メソッドは、テクストを表示するのに使われます。

Figure 7 : 応答のハンドリング

JavaScript:
  if(translation.fault){
    // error returned from the web service
    alert(translation.fault.faultString);
  } else {
    // we expect only one return SOAPParameter - the translated string.
    var response = new Array();
    response = translation.getParameters(false, {});
    alert("Translation: " + response[0].value);
  }

導入で言及されたように、SOAP 呼び出しは、スクリプトのためのクロスドメインポリシーのままに動きます。テストの目的でセキュリティポリシーを欺く以下の 2 つの方法があります。

  1. ローカルディスクからスクリプトを動作させる。

    コードをハードディスクに保存してください。

    クロスドメインセキュリティモデルは、ローカルハードディスクから実行には作用しません。

  2. クロスドメインアクセスを許可する

    設定でクロスドメインを回避することが出来ます。お勧めの設定は、 Bypassing Security Restrictions and Signing Code に説明があります。そして、クロスドメインチェックを上書きを要求する JavaScript コマンドが載っています。

    チェックを回避した後、ブラウザを動かし、ここmodified example page を読み込んでください。SOAP 呼び出しを生成する機能のためにクロスドメイン(このセッションの)を切るのを許可するか(ダイアログで)聞いてきます。変更する場所は、SOAP 呼び出しを生成する機能に netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); を追加するだけです。

Figure 8 : 最終的なコード - Local example, Cross-Domain example

JavaScript:
  var babelFishCall = new SOAPCall();
  babelFishCall.transportURI = "https://services.xmethods.net:80/perl/soaplite.cgi";

  // SOAP params
  var param1 = new SOAPParameter();
  param1.value = "en_fr";
  param1.name = "translationmode";

  var param2 = new SOAPParameter();
  param2.value = "I am";
  param2.name = "sourcedata";

  // combine the 2 params into an array
  var myParamArray = [param1,param2];

  babelFishCall.encode(0, "BabelFish", "urn:xmethodsBabelFish", 0, null, myParamArray.length, myParamArray);

  var translation = babelFishCall.invoke();

  if(translation.fault){
    // error returned from the web service
    alert(translation.fault.faultString);
  } else {
   // we expect only one return SOAPParameter - the translated string.
   var response = new Array();
   response = translation.getParameters(false, {});
   alert("Translation: " + response[0].value);
 }

Soap Envelope を追跡する

ここでは、例を実行したときに、実際に受け渡しされたデータの HTTP ダンプを (クロスプラットフォームな Wireshark ツールを使って) 見ます。

Figure 9 : HTTP ダンプ

送信:
POST /perl/soaplite.cgi HTTP/1.1
Host: services.xmethods.net:80
...
Content-Type: text/xml
Content-Length: 516

<env:Envelope xmlns:env="https://schemas.xmlsoap.org/soap/envelope/"
              xmlns:enc="https://schemas.xmlsoap.org/soap/encoding/"
              env:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"
              xmlns:xs="https://www.w3.org/1999/XMLSchema"
              xmlns:xsi="https://www.w3.org/1999/XMLSchema-instance">
  <env:Header/>
  <env:Body>
      <a0:BabelFish xmlns:a0="urn:xmethodsBabelFish">
          <a0:translationmode xsi:type="xs:string">en_fr</a0:translationmode>
          <a0:sourcedata xsi:type="xs:string">I am</a0:sourcedata>
      </a0:BabelFish>
  </env:Body>
</env:Envelope>


受信:
HTTP/1.1 200 OK
Date: Tue, 11 Mar 2003 20:28:11 GMT
Server: Apache/1.3& (Unix) Enhydra-Director/3 PHP/4.0.6 DAV/1.0.3 AuthNuSphere/1.0.0
SOAPServer: SOAP::Lite/Perl/0.52
Content-Length: 532

...
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENC="https://schemas.xmlsoap.org/soap/encoding/" 
                   SOAP-ENV:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"
                   xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="https://www.w3.org/1999/XMLSchema-instance"
                   xmlns:xsd="https://www.w3.org/1999/XMLSchema">
  <SOAP-ENV:Body>
    <namesp1:BabelFishResponse xmlns:namesp1="urn:xmethodsBabelFish">
      <return xsi:type="xsd:string">je suis</return>
    </namesp1:BabelFishResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

資料

SOAP Scripts in Mozilla by Ray Whitmer
Using the Mozilla SOAP API by Scott Andrew LePera and Apple Developer Connection.
The Latest w3.org SOAP Specification
Calling SOAP Servers from JS in Mozilla OnLamp.com article by Zachary Kessin
SOAPCall documentation on XULPlanet.com
SOAPResponse documentation on XULPlanet.com

原文書の情報

ドキュメントのタグと貢献者

 このページの貢献者: teoli, Marsf, Mgjbot, Okome, STT
 最終更新者: teoli,