Help us understand the problem. What is going on with this article?

JavaScriptで半角記号をGETメソッドで投げたらURLクエリパラメータが消失した話

概要

SpringBootの@RestControllerで作成した@GetMappingエンドポイントに対して
以下の様にtype: 'GET'でクエリパラメータを送信したところ、
パラメータによってエンドポイント側でnull値で受け取る事象やエンドポイントに到達せずにエラーとなる(HTTP500エラーが返る)事象が発生。

個別処理
function test(param1, param2) {
    sendEndpoint(
        {
            type: 'GET',
            url: '/test1/get?param1=' + param1 + '&param2=' + param2,
            dataType: 'json',
        }, function(responseJson) {
            if(responseJson.error) {
                showError(param1, responseJson.errors);
            }
        }
    );
}

※ sendEndpoint()はAjaxでリクエストを投げコールバックを受け取る共通関数

原因

どうやらパーセントエンコーディング対象文字(%)やRFC2396での予約文字を渡してしまうと不具合が発生する模様。

1. パラメータに'%'が含まれる場合

⇒ リクエストパラメータが欠落してnullになる。

2. パラメータにRFC2396の予約文字('|'や'\'など)が含まれる場合

⇒ エンドポイントに到達せず、HTTP500エラーが返る。

※ java.net.URIはRFC2396準拠の様です。

解決策

個別処理のURL部分をencodeURI関数で括る。
参考:encodeURI() | JavaScript 日本語リファレンス

個別処理
function test(param1, param2) {
    sendEndpoint(
        {
            type: 'GET',
            url: encodeURI('/test1/get?param1=' + param1 + '&param2=' + param2),
            dataType: 'json',
        }, function(responseJson) {
            if(responseJson.error) {
                showError(param1, responseJson.errors);
            }
        }
    );
}

最後に

もっといい感じに対応するのであれば
共通処理の方でGETメソッドかPOSTメソッドか判定取ってGETメソッドの時だけ適用する。(POSTは対応不要)のが良いかと思います。

takeday
tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away