キャッシュを用いるが、変更を確実に反映する方法

以下はJAVAJSPを用いたwebプログラムを想定しています。


js(JavaScript)とかcssとかをチョロっと直して
動作確認すると
「あれ??直したはずなのに反映されてない!?」
ってことよくありますよね??

僕はめっちゃくちゃよくありました!!!


新人のころはマジでなぜなのかわからず、先輩に聞くと

先「あーキャッシュねはいはい。コントロールF5でなおるよ。」

僕「こんとろーるえふご…。」

え?同時押し?同時押しだよね??

えいっ。

…ほんまや。

なんなんこれ…。

くっそ不便じゃん…。

とかなんとか思いながらもまぁそんなもんなんだろうなと。
みんなこのクソ仕様とうまく付き合って生きているんだなと思ってたわけです。

でもまぁ経験を積むと回避方法があることを知っていくわけですよね。


jsとかcssの引数(クエリ文字)が変更されると再読込されることを知ります。
以下の「?aaa=123」の部分です。
<script type="text/javascript" src="sample.js?aaa=123">



初めて対処をしていたプログラムでは
「ファイル毎に手書きで変えてね」って仕組みでした。
アホすぎだろ。

次に見たプログラムでは123の部分が定数化してあって
「定数を変えれば全部読み込み直すよ」って仕組みでした。
結構楽になったね。でも書き換え忘れるよね。

さらに他にあったのは
「ランダム値を付与するよ」って仕組みでした。
おお。これはナイス。とても楽。
でもキャッシュ全く機能しないんすけどこれで本当にいいの??

まぁここまでくると
もっと適切な方法が絶対に存在すると気付くわけです。

「該当ファイルの更新日時を付与する」って方法が
最も良さげだなと思い、組み込むことにしました。


以下サンプルコードとなります。


Common.javaに以下を記述

public class Common {
    public static String getCacheBustingUrl(ServletContext application, String strUrl) {
        try{
            String strRealPath = application.getRealPath(strUrl);
            File file = new File(strRealPath);
            Date date = new Date(file.lastModified());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            return strUrl + "?cb_date=" + sdf.format(date);
        }catch(Exception e){
            return strUrl;
        }
    }
}


JSP側に以下を記述

<script type="text/javascript" src="<%=Common.getCacheBustingUrl(application, "test.js")%>"></script>



こんな感じです。

みんな大喜びでした。
めでたしめでたし。

jQueryDialogをhtmlを使用せずに表示

jQueryダイアログをjsのみの記述で表示させる方法です。

var jQueryDialog = $("<div>メッセージ</div>");
jQueryDialog.dialog({
    title: "タイトル",
    resizable: true,
    modal: true,
    width: "auto",
    close: function() {
        $(this).dialog("destroy");
    },
    buttons: {
        "OK": function() {
            $(this).dialog("close");
        }
    }
});

htmlへの記述が不要なため、かなり便利です。
関数化してタイトルやメッセージを引数にすると
更に良い感じになります。

テキストエリアの文字列の長さを取得

テキストエリアの文字列は
単純にそのまま .length で長さを取得しようとすると、
改行の文字列が正しくカウントされません。

一度、別の文字列に置き換えることで正しくカウントできます。

/**
 * テキストエリアの文字列の長さを取得
 */
function getTextAreaLength(str){
    // 改行が正常にカウントされない場合があるため、別の文字列に置換
    var tmpStr = str;
    tmpStr = tmpStr.replace(/\r/g, "AA");
    tmpStr = tmpStr.replace(/\n/g, "AA");
    return tmpStr.length;
}

jQueryDialogの右上の×閉じるボタンを非表示にする。

jQueryダイアログの右上の[×]閉じるボタンを消すには
cssに以下を記述することで実現できます。

button.ui-dialog-titlebar-close{
  display: none;
}

一括で設定する場合は
共通cssにこの記載をする方法が最も手軽かと。


「このダイアログだけは閉じるボタンを表示させたい」
という場合は以下の様に記述します。

$("#testDialog").dialog({
  title: "タイトル",
 
  open: function() {
        $(".ui-dialog-titlebar-close", $(this).closest(".ui-dialog")).show();
  }
});


逆に「このダイアログだけは閉じるボタンを非表示にさせたい」
という場合は以下の様に記述します。

$("#testDialog").dialog({
  title: "タイトル",
 
  open: function() {
  $(".ui-dialog-titlebar-close", $(this).closest(".ui-dialog")).hide();
  }
});

上記の記述を行うことで
複数のダイアログに対し、
個別に閉じるボタンの表示非表示の設定が可能となります。

ひとつ目のダイアログは閉じるボタンあり
そこから更に開くダイアログには閉じるボタンなし
等の動作をさせることができます。

数字のみ抽出

JavaScriptで文字列から数字のみを抽出(他の文字を削除)する処理です。
正規表現を利用します。

tmp = tmp.replace(/[^0-9]/g, "");


他サイトで
replace(/[^0-9]/i, "");
とすれば良いとの記述があったので、
特に意味を調べずにそのまま利用しようとしたら
想定どおりに動きませんでした…。
gにすると正しく動作しました。

iやgについては
正規表現フラグと呼ぶそうです。

g  すべての一致に対して置換を実施。
i   大文字・小文字を区別しない検索。
m 複数行の文字列に対する処理で^や$を扱う場合に使用。

gが無かった為、ひとつ目の置換で終わってしまい、
ふたつ目の置換が実施されないという動きになってしまっていました。