- 締切済み
リロード対策について困っています
本の貸出システムを作っていまして、貸出処理も返却処理も作成し、本の貸出登録後、F5キーなどを押すと「このページを再表示するには以前送信した~~~」とアラートが出て、「再試行」をクリックすると返却処理をしてしまうのですが、これを誤って「再試行」押してしまっても貸出処理を行わないようしたいのですが、どのようにしたら良いのでしょうか?また、別の方法はありますでしょうか? 必要があればソースコード載せます。 上司の方から「CGIが全く同じパラメータで連続して呼ばれるわけですから、CGI側で前どんな処理をしたかを覚えておけば、2度目以降をはじくことはできるはずです。」と言われたのですがそのやり方が良く分かりません。 あとかろうじてリロード対策でWalrus::Session::Liteを使うという所まで分かり、一応試しにhttp://d.hatena.ne.jp/d4-1977/20050706/1120670844のと同じサンプルを作ってみたのですが、15行目のmy @ID = tied(%session_data)->list_session_id; の所でエラーで引っかかりCan't call method "list_session_id" on an undefined value at /usr/local/apache2/cgi-bin/test.cgi line 15, <DATA> line 64. というエラーを吐き出すのですが、経験者の方で原因がお分かりになる方はいらっしゃいますでしょうか?
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- kt_yuka
- ベストアンサー率53% (8/15)
気軽に答えてるので参考程度にしてください。 えっと、貸出登録後にリロードすると返却処理をするということは、 貸出処理と返却処理は同じロジックを使ってるってことですかね? 「貸し出されてた場合は返却、返却されている場合は貸出」なのかな? ご指定のようにセッションに保存してチェックしても良いでしょうし、 最初の処理の前に一意のキーみたいなものを用意できるのであれば、 そのキーが一致した場合には処理しない、みたいにもできるでしょう。 (その処理以前に生成しないと、リロードで別のキーが生成されちゃいますけど) で、私のよくやる回避策ですが、 貸出処理を行った後、Locationを別の画面、例えば「完了しました」と表示 するだけの画面にとばしちゃいます。で、この画面では何の処理もしません。 この画面をリロードしても何の問題も無いですからね。 Walrus::Session::Lite は、ちょっと使ったことありましたけど忘れちゃいました。 ごめんなさい。 他にもCGI::SessionやApache::Sessionも探してみてください。 ちなみに私は上記3つとも、アクセスが集中した時に誤動作を起こしたので、 セッション管理は自前でシンプルに行ってます。
補足
kt_yuka様ありがとうございます。 >>貸出処理と返却処理は同じロジックを使ってるってことですかね? という事ですが貸出中か貸出可能かという「状態」という列を作成してものをDB登録させてif文で状態が貸出中なら返却処理を貸出可能なら貸出処理をしているという状況です。 また、別の方法でフラグを立てるやり方もあるみたいで、 最初の状態=まだ押していない状態=貸し出し処理をしていない、 DBは貸し出しフラグ「0」の状態のはず。ここでボタンが押されたら、貸し出し処理。貸し出しフラグ「1」を記録する。 ここで、ユーザーが2度押しというか更新ボタンを押したとする。 しかし、DBには貸し出しフラグ「1」がすでに記録されているはず。 だから、「あなたはもう借りてるよ」とか出して やればいい。みたいな事も言われましたが、自分の書いたコードでは全く意味がなく歯が立たないです。