- - PR -
この問題についてぜひ知恵をお貸しください
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-04-19 11:02
画面A、画面B、画面Cがあります。
画面Cから画面Bになるべく戻るボタンで戻られたくありません。 もし戻った場合、画面Bを飛ばして画面Aに戻りたいです。 画面A、画面C、(画面D)、は同一サーバーでDBは使えます。 画面Bは別サーバーでDBは使えません。 ここで考えたのは画面AでプライマリーキーをDBに入れ画面CでDBから削除します。 プライマリーキーは引数でも画面AからCまで送られます。 画面B、画面Cの間に画面Dを挟んでJavascriptのlocation.hrefで画面Bから画面Cに 自動的に遷移させます。 (JavaのforwardやsendRedirectでは私が知っている限りでは履歴に残らないので 画面Cで戻るボタンを押したとき画面Bに戻ってしまいます。) これで画面Cで戻るボタンを押した場合画面Dに戻りDB検索をしてプライマリーキーを 検索し画面Cで削除されているので、ない場合は画面Aに遷移させることができます。 ここで問題なのですがユーザーがJavascriptを切っている場合、画面Bから画面Dに 遷移した場合location.hrefが効かないので画面Cに遷移できなくなってしまいます。 forwardやsendRedirectで履歴に残せるようにする方法 (そのページに戻るボタンを押した場合戻れる方法)、又はJavaでJavascriptが有効か 判断できる方法、JavascriptからJavaにパラメーターを渡せる方法いづれかがあれば 画面Dの問題が解決できるのですが知っておられる方ご教授おねがいします。 >JavaでJavascriptが有効か判断 はJavascriptが有効でない場合forwardやsendRedirectの処理を行い、現時点では履歴に残らないので戻るボタンの処理は行わないようにしようと考えています。 [ メッセージ編集済み 編集者: matsu_on 編集日時 2005-04-19 11:19 ] | ||||
|
投稿日時: 2005-04-19 12:08
2chのプログラム板に質問していたのはあなたですか? 2chとはいえ、筋は通したら?
この方法では、戻るボタンはなんとかできても、履歴をたどられたらやはり画面Bに遷移できて しまいます。やるとすれば履歴を削除するしかありませんが、そのような方法はないでしょう。 そもそもなぜそのような処理をしたいのか書いてみたらどうでしょうか。 | ||||
|
投稿日時: 2005-04-19 12:18
返答ありがとうございます。
画面Bではサーバーに非常に負荷の高い処理を行いますので画面Aで遷移ボタンを押すと 並び順処理を行っています。並び順で1人づつ画面Bの処理を行うようにしてます。 ですが現在画面Cで戻るボタンを押すと画面Bに戻ってその処理が始まってしまうので 画面Aの並び順の意味が半減してしまい、セキュリティホールのような感じになって しまっています。 ですので画面Cで戻るボタンを押すと並び順を行う画面Aに戻りたいのです。 | ||||
|
投稿日時: 2005-04-19 12:28
要するに規定の遷移順でなければ実行しないようにしたいわけですね。
であれば、トランザクション・トークンという手法が使えます。具体的な実装方法はネットで 検索すればいろいろ出てくると思います。 | ||||
|
投稿日時: 2005-04-19 14:18
<重複submitを防ぐトランザクショントークンという考え方>
適用例: submitボタンを二度押ししてしまったりすることで発生する 掲示板での二重投稿、注文フォームでの二重送信などを防止。 フロー: (1) フォームを表示するPHPスクリプトにおいて、 「トランザクショントークン」を生成する。 なんでもいい。ランダムな文字列でよい。 (2) フォームを表示するPHPスクリプトにおいて トークンをセッションに登録し、かつ、フォームの hidden項目にも同じトークンをセットする (3) POSTされたデータを受け取るPHPスクリプトにおいて、 次の処理をする 1. hiddenで渡ってきたトークンとセッションに保存されている トークンが一致すれば真性とみなし、 正常な処理をすると同時にセッション上のトークンを削除する 2. hiddenで渡ってきたトークンとセッションに保存されている トークンが一致しなければ二重投稿または何らかの不正とみなし、 エラーとする。 引用:http://ns1.php.gr.jp/pipermail/php-users/2003-December/019965.html を見て試してみたのですが別サーバ(画面B)にセッションIDが渡らないので 無理なようです。 全体の構成を見直して見ます。 ありがとうございました。 | ||||
|
投稿日時: 2005-04-19 14:46
であればサーバBでは逆に実行済みのトークンをセッションに保存しておいて、実行済みトークン
を指定したリクエストをはじけばいいのではないでしょうか。 | ||||
|
投稿日時: 2005-04-19 18:37
ご返答ありがとうございました。
画面Bに以下の記述を加えました。 int flg = 0; HttpSession session1 = request.getSession(false); String messages = (String)session1.getAttribute("ID"); //もしセッションが有効で下で設定された数字が入っていた場合 //(戻るボタンを押した場合)セッションを破棄し、遷移フラグを立てる if (session1 != null && (random_p2).equals(messages)) { session1.invalidate(); session1 = null; messages = null; flg = 1; } if(session1 != null){ session1.invalidate(); } session1 = null; messages = null; if(flg == 1){ //遷移フラグがたっていた場合、Servletを通して画面Aに遷移 %> <SCRIPT language=JavaScript> <!-- location.href("http://localhost:8080/servlet/classes.〜Servlet?param=to_a〜"); //--> </SCRIPT> <% } // セッション開始 HttpSession session2 = request.getSession(true); session2.setMaxInactiveInterval(300); // セッションに画面Aで発生させたランダムな数字を設定 session2.setAttribute("ID" , random_p2); なお画面Bでは戻るボタンを押した場合キャッシュを読み込まないように <%@ include file="Nocache.inc" %> によりNocache.incをインクルードしてます。 これにより履歴を戻る(戻るボタンを押す)ごとにセッション取得部分でセッションを 読み込みなおすことができました。 Nocache.inc <%! private String getHTTPDate() { java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("E, dd MMM yyyy hh:mm:ss zzz", java.util.Locale.US); formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT")); return formatter.format(new java.util.Date()); } %><% response.setHeader("Expires", getHTTPDate()); response.setHeader("Pragma","no-cache"); response.setHeader("Cache-Control","no-cache"); %> まだロジックの検証をしていますがこの仕組みによりJavascriptが有効な場合は 画面Cで戻るボタンを押した場合画面Aに戻り、無効にしていた場合でも画面Cで 戻るボタンを押したら画面Bに戻ってしまいますが、画面Bから画面Cに遷移できる ようになりました。 あきらめようと思っていましたがukさんの適切なヒントにより目的の動作を 達成できるようになりました。 本当にありがとうございます。 これからは質問の仕方にも気をつけるようにします。 失礼します。 [ メッセージ編集済み 編集者: matsu_on 編集日時 2005-04-19 18:46 ] |
1