記事
· 2026年2月15日 4m read

#server()#が突然使えなくなるかもしれません

IRISではCSPタグベースの開発は、非推奨(Deplicated)になっています。

非推奨とはいえ、いますぐ使えなくなることはないと思います。

が、CSP機能に含まれるHyperEventの#server()#呼び出しは、かなりやばいということがわかってきました。

これはChromeを始めとするメジャーなブラウザーが提供しているSynchronous XMLHttpRequestという関数を呼び出しています。

この関数をGoogleは10年前くらいから非推奨機能としていて、いつか完全に機能をドロップすると宣言しています。

Stackoverflowの該当記事

インターシステムズのドキュメントにもさりげなく記載されています。

HyperEventCallメソッド

とはいえ、10年もそのままなので、希望的観測をすれば、今後も使える可能性は高いかもしれません。

しかし、ある日突然なくなるリスクはゼロではありません。

ですので、#server()#呼び出しをお手元のコードからなるべく早く取り除くのが賢明です。

それでは、どうすれば良いのか?

ということですが、今のご時世で考えれば、REST APIに変えましょうというのが美しい世界ですが、おそらく書き換えのコストは、半端じゃないでしょう。

ということで、現実的な解は、#Call()#に置き換えることだと思います。

しかし、#call()への書き換えも一筋縄ではいかない可能性をあります。

#serverと#callの最大の違いは、#serverの場合は、戻り値を取得できる点です。

そして、この戻り値を返すようなコーディングをしている場合、書き換えは結構手間がかかる可能性が高いです。

一方、戻り値がなく、呼び出されるメソッド内で処理が完結する場合は、単純な文字列置き換えで済む可能性があります。

最も単純なパターンを考えてみます。

以下は、#server()#の戻り値をテキストボックスの値(value)に直接設定する例です。

<!--フォームの記述-->
<form name="f1">
<input type="text" value="" name="text1">
<input type="button" value="test" onclick="runMyRoutine();">
</form>
<!-- ボタンクリックで最初に呼び出されるJavascript関数 -->
<script language="javascript">
function runMyRoutine() {
self.document.f1.text1.value = #server(..MyMethod('Hiroshi'))#;
}
</script>
<!-- Javascriptの#serverから呼び出されるIRISメソッド -->
<script language="cache" method="MyMethod" arguments="Name:%String" returntype=%String>
Quit "Hello "_Name
</script>

#call()#は戻り値を返せないので、代わりに以下のような形に変更する必要があります。

つまり呼び出されるメソッドの中で&javascript(マクロ or ディレクティブ)を使用して、フォームのコンポーネントに設定する必要があります。

<!--フォームの記述-->
<form name="f1">
<input type="text" value="" name="text1">
<input type="button" value="test" onclick="runMyRoutine();">
</form>
<!-- ボタンクリックで最初に呼び出されるJavascript関数 -->
<script language="javascript">
function runMyRoutine() {
#call(..MyMethod('Hiroshi'))#;
}
</script>
<!-- Javascriptの#callから呼び出されるIRISメソッド -->
<script language="cache" method="MyMethod" arguments="Name:%String" returntype=%String>
&javascript< CSPPage.document.f1.text1.value = 'Hello #(Name)#'; >
Quit "Hello "_Name
</script>

 

実際には、複数の項目をまとめて戻り値として取得し、それをJavascriptで分解して、各コンポーネントに設定するということも行なっている場合には、修正もより複雑になっていく可能性があります。

そして&javascriptの多用は、通信という観点では、非常にコストが高く、特にレイテンシー(応答時間の長さ)のペナルティが大きいです。

WIFI経由でアクセスする要件がある場合は、注意が必要です。

やはり理想的にはREST APIで一般的な非同期通信のお作法に則ったプログラミングを行い、取得するデータはなるべく1つのJSONとして取得し、クライアントで各コンポーネントを更新するという方法が今時の推奨になります。

ディスカッション (1)1
続けるにはログインするか新規登録を行ってください

このシンプルな例をREST APIで書き換えるとこんな感じです。

まずはCSPファイルです。

<html>
<body>
<!--フォームの記述-->
<form name="f1">
<input type="text" value="" name="text1">
<input type="button" value="test" onclick="runMyRoutine();">
</form>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- ボタンクリックで最初に呼び出されるJavascript関数 -->
<script language="javascript">
function runMyRoutine() {
  axios.get('http://localhost:8080/api/user/getMessage/Hiroshi')
  .then(response => {
   console.dir(response)
   self.document.f1.text1.value = response.data.Message
  })
  .catch(error => {
    console.log(error)
  })
  }
</script>
</body>
</html>


次に呼び出されるREST APIのクラスです。

Class Samples.API Extends %CSP.REST
{

Parameter CONVERTINPUTSTREAM = 1;

XData UrlMap
{
<Routes>
  <Route Url="/getMessage/:name" Method="GET" Call="GetMessage"/>
</Routes>
}

ClassMethod GetMessage(pName As %String) As %Status
{
  set status = $$$OK

  try {
	
    if $data(%request) {
      set %response.ContentType="application/json"
      set %response.CharSet = "utf-8"
    }
    set return = {}
    set return.Message = "Hello "_pName
    write return.%ToJSON()
	  	  
  }
  catch e {
		
    set status = e.AsStatus()
		
  }
  
  quit status
}

}


RESTアプリケーションの設定例