2008-09-22

Aptana Jaxer は同名パラメータの複数値を扱えないので個別の対応が必要です

チェックボックスを並べた送信フォームを用意し、そのチェックボックスのパラメータ名(input@name)を同じにして、送信先で、その複数のパラメータ値を取得する... といったことは、ウェブアプリケーションの開発でよく使うパターンです。

ですが、Aptana Jaxer の Jaxer.Request クラスは、同名パラメータの複数値を扱えないため、個々のパラメータ名を重複しないようにするか、Jaxer.Request を使わない個別の対応が必要です。

Jaxer の実装がどうなっているかというと、GET メソッドのときは、次のとおり、QUERY_STRING を解析しています。同じパラメータ名があると、後のパラメータ値で上書きしています。

var queryStrings = query.split("&");
for (var i = 0; i < queryStrings.length; i++)
{
var nameValue = queryStrings[i].split("=");
hash[Util.Url.formUrlDecode(nameValue[0])] = (nameValue.length > 1)
? Util.Url.formUrlDecode(nameValue[1])
: null;
}

POST メソッドのときは、次のとおり、HTTP ボディを解析しています。GET メソッド同様に、同じパラメータ名があると、後のパラメータ値で上書きしています。

var postCount = _request.GetDataItemCount();
for (var i = 0; i < postCount; i++)
{
var name = _request.GetDataItemName(i);
var value = _request.GetDataItemValue(i);
data[name] = value;
}

この Jaxer.Request クラスの良し悪しを簡単に断定することはできません。が、RPC ベースの Jaxer Callback を主体とする Jaxer としては、用途を限定することを知りつつも、HTTP リクエストのデータ構造を単純にして、手軽さを採用したのだと推測しています。

ですので、同名パラメータの複数値を扱いたいときは、Jaxer.Request クラスのパラメータ解析に頼らず、次のように、自らのコードでパラメータを解析することになります。

このコードは、POST メソッドのとき、subscriber というパラメータが複数の値になることを前提としています。GET メソッドのときは Jaxer.Request.query プロパティ、POST メソッドのときは Jaxer.Request.postData を解析するとよいでしょう。

var subscribers = [];
request.postData.split('&').forEach(function(param) {
param = param.split('=');
if (param[0] == 'subscriber')
subscribers.push(param[1] || '');
});

なお、ここで扱った Aptana Jaxer のバージョンは 0.9.7.2472 (Linux) です。ですので、公開中の 1.0.0 RC B では改善されているかもしれません。

0 件のコメント: