SpringBoot+ThymeleafでAjax処理してHTMLを部分的に書き換える場合があります。
検索処理をAjaxでやって検索結果のところだけ動的に書き換える、みたいな感じですね。
別にSpringBoot+Thymeleafじゃなくたってありますが。
SpringBootと言ってますが要はSpringMvcですね。
この組み合わせでやるとき、Controllerの戻り値を
Return "hogehoge:fugafuga"
のようにしてth:fragmentを指定した一部分のHTMLだけを返すようにします。
こんな感じですね。
「検索」、「クリア」のあと、「前へ」の手前までの部分がfragmentになっています。
が、こうしているとセッションタイムアウトしている場合に悲劇が発生します。
こうなります。
fragmentの部分にログイン画面がはまってしまいました。
SpringSecurityの認証フィルタを使うとタイムアウトしている場合は自動的にログイン画面に飛ばしてくれるのですが、ajaxでfragment部分だけ戻している場合も例外では無く。
さてさて、これでは大変見栄えがよろしくないのでなんとかしたいところです。
しかしサーバーサイドではSpringSecurityがばっちり拾ってくれているので介入のしようが無く、クライアントサイドでは正常(ステータスコード=200)でログイン画面が返ってきます。
さてどうしたものか。
返ってきたのがログイン画面だったらリダイレクトすればいいじゃない。
というわけでログイン画面にコメントで目印を埋め込んで・・・
<!DOCTYPE html> <!-- this is login form -->
<html xmlns:th="http://www.thymeleaf.org">
それを見つけたらリダイレクト!
// タイムアウトしてから検索すると、検索エリアにログイン画面が埋め込まれる事象の対応
$(document).ajaxSuccess(function(e, xhr, options){
// レスポンスにDOCTYPEが含まれたらログイン画面と判断する
if(xhr.responseText.match(/<!-- this is login form -->/)){
// ログイン画面を受信した場合は自画面に遷移させる(ことで親画面をログイン画面にする)
window.location.href = './';
return false;
}
});
fragmentでは含まない<!DOCTYPE html>
を拾おうかとも考えたのですが、一応ログイン画面に限定した実装にしておこうかと。
力技ですのでもっとスマートなやり方をご存じの方は是非コメントをお願いします。