ServiceNowのGlideAjaxとは何か – クライアントサイドからScript Includeを呼び出すための仕組み

開発・導入

クライアントサイドスクリプトからサーバーサイドスクリプト(Script Include)を呼び出すための仕組みであるGlideAjaxについて解説します。

なお、Script Includeの説明はこちらの記事を参照ください。一部の説明は重複しています。

GlideAjaxとは?

GlideAjaxのイメージ

GlideAjaxとは、クライアントサイドスクリプトから、サーバーサイドスクリプト(Script Include)を呼び出すための仕組みです。

なぜGlideAjaxが必要か

では、なぜこのような仕組みが必要なのでしょうか。

まず、クライアントサイドスクリプトは画面にアクセスした際にサーバー=インスタンスからクライアント=ブラウザに返されるページの中に埋め込まれています

クライアントサイドスクリプトのイメージ

そのため、クライアントサイドスクリプトは基本的にクライアントサイド=ブラウザ=画面上の情報のみを使って処理・制御を行います。具体歴な例としては「Order No.項目が入力されたとき、桁数をチェックし、条件を満たさない場合はエラーを出す」といった制御が該当します。

クライアントサイドで完結するクライアントサイドスクリプトの例

しかし、クライアントサイド=ブラウザ=画面上の情報だけでは処理・制御ができない場合があります。例えば、「Applicant項目が入力されたとき、ユーザが所属する部署の部長をManager項目に自動で設定する」という処理をしたいときは、サーバーサイド=インスタンスにあるユーザ情報を参照する必要があります

サーバーサイドの情報が必要なクライアントサイドスクリプトの例

このとき必要になるのが、クライアントサイドスクリプトからサーバーサイドスクリプトを呼び出す仕組みであり、この仕組みがGlideAjaxです。クライアントサイドスクリプトで必要になる情報を取得するサーバーサイドの処理をScript Include(Client callable)で書いておき、これをクライアントサイドスクリプトからGlideAjaxを用いて呼び出すことで、クライアントサイドでサーバサイドの情報を用いた処理を実行できます。

サーバーサイドの情報が必要なクライアントサイドスクリプトの例

GlideAjaxを用いたClient callable Script Include呼び出しの流れ

GlideAjaxを用いたClient callable Script Includeの呼び出方しには、非同期呼び出しと同期呼び出しの2パターンがあります。なお、同期呼び出しでは応答時間が長くなるため、非同期呼び出しが推奨されています。そもそも非同期とか同期って何?コールバック関数って何?という方は、この記事の最後に補足したので、必要に応じてご参照ください。

非同期呼び出し(推奨)

非同期呼び出しの場合の流れは次の通りです。

非同期呼び出しの流れ
  1. (クライアントサイドの呼び出し側処理) GlideAjaxを用いてScript Includeを呼び出す
    – コンストラクタで呼び出すScript Include名を指定
    – addParam()で呼び出す関数と引数を指定
    – コールバック関数を指定して非同期呼び出し

    ※ 非同期呼び出しであるため、呼出し後は待たずに次の処理へ
  2. (サーバーサイド)Script Includeで処理を行い結果を返す
    – getParameter()で引数を取得
    – サーバーサイドで処理を行う
    – returnで結果を返す
  3. (クライアントサイドのコールバック関数)Script Includeの処理結果を用いて処理を行う
    – コールバック関数で結果を受け取る
    – 結果を用いた後続処理を実行

同期呼び出し(非推奨 & Globalのみ)

同期呼び出しの場合は次のようになります。なお、応答時間が長くなるため非推奨であることと、Globalスコープでしか使えないので注意が必要です。

同期呼び出しの流れ
  1. (クライアントサイド) GlideAjaxを用いてScript Includeを呼び出す
    – コンストラクタで呼び出すScript Include名を指定
    – addParam()で呼び出す関数と引数を指定
    – 同期呼び出し

    同期呼び出しであるため、呼出し後は結果を待つ
  2. (サーバーサイド)Script Includeで処理を行い結果を返す
    – getParameter()で引数を取得
    – サーバーサイドで処理を行う
    – returnで結果を返す
  3. (クライアントサイド)Script Includeの処理結果を用いて処理を行う
    – getAnswer()で結果を受け取る
    – 結果を用いた後続処理を実行

GlideAjax + Client callable Script Includeの設定方法

ここからは、具体的な設定方法を説明します。処理の起点はGlideAjaxですが、実際に設定を行う際には、Script Include側から行います。

Script Include側の設定方法

Script Include側の設定方法はこちらの記事で説明しています。

以下、上記の記事で示している下記のScript Includeを前提として、どのように呼び出すかを説明します。

var MyClientCallableScriptInclude = Class.create();
MyClientCallableScriptInclude.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    serverFunc: function(/* この中には引数を定義しない */) {
        var arg1 = this.getParameter('sysparm_arg1'); // 引数"sysparm_arg1"を取得
        var arg2 = this.getParameter('sysparm_arg2'); // 引数"sysparm_arg2"を取得
		return arg1 + arg2;
    },

    type: 'MyClientCallableScriptInclude'
});

クライアントサイドスクリプト(GlideAjax)の設定方法(非同期)

onLoadのClient Script内から呼び出す場合を例に、非同期でScript Includeを呼び出す場合のコードを示します。非同期呼び出しの場合、2つの方法があります。

getXML()を利用

getXML()を利用する場合は、次のようなコードになります。

function onLoad() {
    var ga = new GlideAjax('global.MyClientCallableScriptInclude'); // Script IncludeのAPI Nameを指定
    ga.addParam('sysparm_name', 'serverFunc'); // 呼び出す関数名を指定
    ga.addParam('sysparm_arg1', 'arg1'); // Script Include側で定義している引数を渡す
    ga.addParam('sysparm_arg2', 'arg2'); // Script Include側で定義している引数を渡す
    ga.getXML(callback); // 非同期でScript Includeを呼び出す

	// Script Include側で処理が終わった際に呼ばれるコールバック関数
	function callback(response) { // Script Includeの処理結果がresponseに渡される
    var answer = response.responseXML.documentElement.getAttribute("answer"); // XML構造の中から結果を取り出す
		// 処理
	}
}

詳細を見ていきます。まずは呼び出すScript IncludeのAPI Nameを引数にしてGlideAjaxクラスのインスタンスを生成します。

 var ga = new GlideAjax('global.MyClientCallableScriptInclude');

次に、呼び出す関数名をaddParam()で指定します。この際、第一引数は必ず’sysparm_name’とします。

 ga.addParam('sysparm_name', 'serverFunc'); // 呼び出す関数名を指定

追加でScript Includeに渡したい引数がある場合はaddParam()で指定します。第一引数はScript Include側のgetParameter()の引数と一致させます

ga.addParam('sysparm_arg1', 'arg1'); // Script Include側で定義している引数を渡す
ga.addParam('sysparm_arg2', 'arg2'); // Script Include側で定義している引数を渡す

最後にコールバック関数を引数にしてgetXML()でScript Includeを呼び出します

ga.getXML(callback); // 非同期でScript Includeを呼び出す

コールバック関数にはScript Includeの結果を受け取る引数を定義しておきます。getXML()を使う場合、コールバック関数に渡されるのはScript Include側でreturnした値そのものではなく、その値を含むXML構造なので次のようにして結果を取り出す必要があります

// Script Include側で処理が終わった際に呼ばれるコールバック関数
function callback(response) { // Script Includeの処理結果がresponseに渡される
  var answer = response.responseXML.documentElement.getAttribute("answer"); // XML構造の中から結果を取り出す
  // 処理 alert('answer: ' + answer);
}

※ なお、コールバック関数は即時関数を使ってもよいです。(Tokyoバージョンからはアロー関数も利用できるようになりました)

getXMLAnswer()を利用 推奨

getXMLAnswer()を利用する場合は、次のようになります。getXMLAnswer()の方が柔軟性があり、かつ結果が取得しやすいため、こちらの利用を推奨します。

function onLoad() {
    var ga = new GlideAjax('global.MyClientCallableScriptInclude'); // Script IncludeのAPI Nameを指定
    ga.addParam('sysparm_name', 'serverFunc'); // 呼び出す関数名を指定
    var additional_parms = { // 追加パラメータを連想配列(Dictionary)で定義
        'sysparm_arg1': 'arg1',
        'sysparm_arg2': 'arg2'
    };
    ga.getXMLAnswer(callback, additional_parms, "2nd parm of callback func"); // 非同期呼び出し

    // Script Include側で処理が終わった際に呼ばれるコールバック関数
    function callback(answer, response_parm) { // answerにScript Include側の関数の戻り値が格納される
        // 処理 alert('answer: ' + answer + ', response_parm: ' + response_parm);
    }
}

基本的な流れはgetXML()の場合と同じですが、いくつか異なる点があります。

一点目は、getXMLAnswer()の第二引数を用いることで、追加のパラメータ(Script Includeに渡す引数)を連想配列(Dictionary)で渡すことができるという点です。必須で指定する’sysparm_name’と追加のパラメータがコード上で区別しやすく可読性が上がると思います。なお、getXML()と同様にaddParamで渡すこともできます。

二点目は、getXMLAnswer()の第三引数を用いることで、呼び出し側の処理からコールバック関数に値を渡すことができるという点です。getXMLAnswer()の第三引数に指定された値は、コールバック関数の第二引数に格納されます。onChangeのClient ScriptからGlideAjaxを使う場合に、newValueをコールバック関数に渡すといった使い方をします。

三点目は、コールバック関数の第一引数には、Script Include側でreturnした値がそのまま格納される点です。getXML()のように、取り出す処理が不要になるため、使いやすいです。

クライアントサイドスクリプト(GlideAjax)の設定方法(同期)

同期呼び出しの場合は、getXMLWait()を利用します。繰り返しになりますが、応答時間が長くなるため非推奨であることと、Globalスコープでしか使えないので注意です。

function onLoad() {
    var ga = new GlideAjax('global.MyClientCallableScriptInclude'); // Script IncludeのAPI Nameを指定
    ga.addParam('sysparm_name', 'serverFunc'); // 呼び出す関数名を指定
    ga.addParam('sysparm_arg1', 'arg1'); // Script Include側で定義している引数を渡す
    ga.addParam('sysparm_arg2', 'arg2'); // Script Include側で定義している引数を渡す
    ga.getXMLWait(); // 同期呼び出し
    var answer = ga.getAnswer(); // 結果の取得
    // 処理 alert(answer);
}

引数を指定する部分までは、非同期のgetXML()の場合と同様です。

呼び出す部分について、同期処理の場合はコールバックが不要なので、getXMLWait()は引数が不要です。なお、getXMLAnswer()のように追加パラメータ(Script Includeの引数)を連想配列(Dictionary)で渡すオプションはないため、追加パラメータはaddParm()で渡します。

結果の取得にはgetAnswer()を使いますScript Include側でreturnした値がそのまま取得できます

補足

getXML, getXMLAnswer, getXMLWaitのまとめ

GlideAjaxからScript Includeを呼び出すときに使う関数を表にまとめておきます。各関数の詳細は上述しています。

関数方式引数コールバック関数
の引数
Script Includeのreturn値の受け取り方
getXML()非同期第一引数: コールバック関数第一引数: Script Includeのreturn値を含むXMLコールバック関数の第一引数から取得
getXMLAnswer()非同期第一引数: コールバック関数
第二引数: 追加パラメータの連想配列(Dictionary)
第三引数: コールバック関数の第二引数に渡される値
第一引数: Script Includeのreturn値
第二引数: getXMLAnswerの第二引数の値
コールバック関数の第一引数
getXMLWait()同期無し無しgetAnswer()で取得
getXML, getXMLAnswer, getXMLWaitのまとめ

非同期呼び出しと同期呼び出し、コールバック関数とは?

上記では非同期呼び出し、同期呼び出し、コールバック関数という用語を当然のように使いましたが、馴染みがない方に向けて、どのようなものか補足しておきます。

クライアントとサーバー間の通信は、お客さんとお店の間でのやり取りに例えることができます。

クライアント(お客さん)がサーバー(お店)に問合せをするときに、問い合わせた内容をお店の人が調べるのを待たずに、結果がわかったらかけ直してもらう方式を非同期といいます。このとき、クライアント(お客さん)は予めサーバー(お店)にどこにかけ直すかを伝えておく必要があります。このかけ直す先がコールバック関数です。

非同期呼び出しのイメージ

これに対し、お店の人が調べているのを電話口で待つ方式を同期と言います。その場で結果を待つため、かけ直し自体が不要です。

同期呼び出しのイメージ

非同期呼び出しは少し面倒ですが、サーバー(お店)が調べている間、呼び出し処理(お客さん)は別のことができます。

実際のシステムだと、同期呼び出しではサーバーサイドの処理を待っている間、クライアントサイドの処理は止まり、画面がフリーズした状態 = ユーザの操作を受け付けられない状態になってします。そこで、非同期呼び出しを使うことで、サーバー側の処理を待っている間も、処理を継続 = ユーザの操作を受け付けられるようにするのが一般的です。

以上です。

コメント

タイトルとURLをコピーしました