C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[13]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処


(過去ログ 16 を表示中)

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■5524 / inTopicNo.1)  ブラウザによる更新(再送信)のイベント発生の仕組みと対処
  
□投稿者/ ghost_shell (1回)-(2007/07/17(Tue) 15:09:13)
ghost_shell さんの Web サイト

分類:[ASP.NET (C#)] 

開発環境:Visual Studio 2005
使用言語:C#2.0 (ASP.NET 2.0)

ブラウザによる更新(再送信)のイベント発生の仕組みと対処を教えてほしいです。



以下のページを読みました。広範な情報を知りたいので質問します。(書籍でもいいので情報源があればお願いします。)

ASP.NET 更新ボタンを押すと直前のイベントが走ってしまいます。 - Insider.NET
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=18998&forum=7


知りたいのは2点です
・イベント(ボタン)が2つ以上ある場合、現在のフォーカスとは無関係に直前のイベントが発生しているようですが、どうして直前のイベントが分かるのか。
・イベント自体を発生させない、イベント側でボタンが押されたかを判断する、に該当する解決策やその他講じている対処方法について


経験豊富なWeb開発者の皆様のアドバイスをお待ちしています。
引用返信 編集キー/
■5531 / inTopicNo.2)  Re[1]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ Moo (68回)-(2007/07/17(Tue) 17:14:59)
Moo さんの Web サイト
2007/07/17(Tue) 17:16:38 編集(投稿者)
> 知りたいのは2点です
> ・イベント(ボタン)が2つ以上ある場合、現在のフォーカスとは無関係に
> 直前のイベントが発生しているようですが、どうして直前のイベントが分かるのか。
Webブラウザの更新ボタンを押すことにより、そのページを表示させたときと同じリクエストをサーバ送るためです。
これはWebブラウザの機能です。

> ・イベント自体を発生させない、イベント側でボタンが押されたかを判断する、
> に該当する解決策やその他講じている対処方法について
イベントを無効にすべきかどうかをサーバ側で判定してください。
たとえば、Amazonなどの商品購入画面で誤って複数購入しないために2回目の処理を行わないようにする必要があります。

トレースをオンにするとリクエストの情報がわかりやすいですよ。

トレースをオンにするには:
-フォームのロード時に「Trace.IsEnabled = True」を設定してください

引用返信 編集キー/
■5540 / inTopicNo.3)  Re[1]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ Jitta (370回)-(2007/07/17(Tue) 20:45:36)
No5524 (ghost_shell さん) に返信
> 開発環境:Visual Studio 2005
> 使用言語:C#2.0 (ASP.NET 2.0)

応用してください。
http://blogs.wankuma.com/jitta/archive/2005/11/18/19447.aspx
引用返信 編集キー/
■5557 / inTopicNo.4)  Re[2]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ ghost_shell (3回)-(2007/07/18(Wed) 11:48:33)
ghost_shell さんの Web サイト
No5531 (Moo さん) に返信
>>知りたいのは2点です
>>・イベント(ボタン)が2つ以上ある場合、現在のフォーカスとは無関係に
>>直前のイベントが発生しているようですが、どうして直前のイベントが分かるのか。
> Webブラウザの更新ボタンを押すことにより、そのページを表示させたときと同じリクエストをサーバ送るためです。
> これはWebブラウザの機能です。

つまり「このボタンが押された」という情報を保持していて、更新の都度その情報を合わせて送るということですか。


No5540 (Jitta さん) に返信
> ■No5524 (ghost_shell さん) に返信
>>開発環境:Visual Studio 2005
>>使用言語:C#2.0 (ASP.NET 2.0)
>
> 応用してください。
> http://blogs.wankuma.com/jitta/archive/2005/11/18/19447.aspx

クライアント側のOnClientClickだけでやってみようと試みましたが、昨日は失敗に終わりました。
サーバーがタイムスタンプを発行するのはわかりやすいです。

同一データ送信は禁止していないのでボタン多重クリックを外して考えていたのですが、その情報も参考にしてみます。


解決にチャックをしておきますが、引き続きアドバイスをお待ちしています。
解決済み
引用返信 編集キー/
■5566 / inTopicNo.5)  Re[3]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ Moo (73回)-(2007/07/18(Wed) 13:48:37)
Moo さんの Web サイト
No5557 (ghost_shell さん) に返信
> ■No5531 (Moo さん) に返信
> >>知りたいのは2点です
> >>・イベント(ボタン)が2つ以上ある場合、現在のフォーカスとは無関係に
> >>直前のイベントが発生しているようですが、どうして直前のイベントが分かるのか。
>>Webブラウザの更新ボタンを押すことにより、そのページを表示させたときと同じリクエストをサーバ送るためです。
>>これはWebブラウザの機能です。
>
> つまり「このボタンが押された」という情報を保持していて、更新の都度その情報を合わせて送るということですか。
そのとおり。

ポストされたデータには「どのボタンが押されたか」が記録されています。

簡単な例で言うと、Google(google.co.jp)でキーワードを入れて検索すると
「btnG=Google+%E6%A4%9C%E7%B4%A2」というパラメータがリクエストに含まれます。
この場合
「<input type="submit" value="Google 検索" name="btnG" id="btnG">」
のボタンが押されたことがパラメータとして引き渡されているわけです。

HTTPリクエストをモニタリングしてみるとわかりやすいですよ。
(前回説明した「トレース機能」でもポスト内容を確認することができます)
解決済み
引用返信 編集キー/
■5570 / inTopicNo.6)  Re[4]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ 黒龍 (81回)-(2007/07/18(Wed) 15:50:29)
若干の誤解を含んでいそうなので・・・。
更新ボタンやF5などの再表示はリクエストの再送を行い結果として表示が更新されることになります。(なので更新処理のや削除処理の直後であればもう一度処理をしようとする)
この再送されるデータですが現在の画面とは全く無関係で前回表示していたボタンが押された画面から作られたリクエストになるのですが作成済みのリクエストのみ保持している点に注意です。

ブラウザの動きはざっくりと1.ボタン押し->2.リクエスト組み立て->3.送信の流れですが更新では前回送付したリクエストを保持しており3.の送信のみ行います。

通常は諸々の状況を考慮して2度押しの処理を行うのですが今回の更新への対応とイコールにする必要は無いと思います。つまり処理の結果で画面を出すのではなく一度リダイレクトを挟めば更新押しでも送られるデータがなくなりそうにも思いますがいかがでしょうか?
引用返信 編集キー/
■5580 / inTopicNo.7)  Re[5]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ ghost_shell (4回)-(2007/07/18(Wed) 18:31:18)
ghost_shell さんの Web サイト
Mooさん、黒龍さん、書き込みありがとうございます。

更新時には保持していたリクエストを再送するということですね。

>通常は諸々の状況を考慮して2度押しの処理を行うのですが今回の更新への対応とイコールにする必要は無いと思います。つまり処理の結果で画面を出すのではなく一度リダイレクトを挟めば更新押しでも送られるデータがなくなりそうにも思いますがいかがでしょうか?

「更新の場合」にはResponse.Redirectするという意味ですか。
どのようにして「更新の場合」の判別をするのですか。

HttpRequestですかね?
引用返信 編集キー/
■5581 / inTopicNo.8)  Re[6]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ 黒龍 (82回)-(2007/07/18(Wed) 18:45:14)
ややこしいですが「更新の場合=更新ボタンによる再送処理」と理解して返信します。
Redirectすべきは更新時ではなくその手前の処理時です。なにもしなければそのままそのページが返されますがRedirectにすることで前回送信リクエストがクリアされることを期待しての書き込みでした。試して無いので時間を見て試してみます。

引用返信 編集キー/
■5582 / inTopicNo.9)  Re[7]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ 黒龍 (83回)-(2007/07/18(Wed) 19:04:46)
結果ですがクリアはされているようでした。
正攻法で行くならViewStateに何らかのフラグを埋める+クライアントスクリプトでボタンの無効化あたりの処理を行うのも一つの方法だと思います。方法自体はいろいろあるのであまり.NETにこだわらずブラウザやサーバのやり取りの動きを考えてみてはいかがでしょうか?

引用返信 編集キー/
■5583 / inTopicNo.10)  Re[8]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ Jitta (371回)-(2007/07/18(Wed) 19:08:14)
質問!
「戻る」は、考慮しなくてもいいですか?
引用返信 編集キー/
■5643 / inTopicNo.11)  Re[9]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ ghost_shell (5回)-(2007/07/19(Thu) 13:41:39)
ghost_shell さんの Web サイト
No5583 (Jitta さん) に返信
> 質問!
> 「戻る」は、考慮しなくてもいいですか?

気にせず「更新」ボタンを押す癖があるので、このことは突き止めたいな、と思いました。

この質問は実際の案件についてではないし、仕様に書かれていません。
このようにして知識を深めることで、似た事例の際にこちらから解決策に沿った質問や提案ができるのではないか、と思います。


No5581 (黒龍 さん) に返信
> ややこしいですが「更新の場合=更新ボタンによる再送処理」と理解して返信します。
> Redirectすべきは更新時ではなくその手前の処理時です。なにもしなければそのままそのページが返されますがRedirectにすることで前回送信リクエストがクリアされることを期待しての書き込みでした。試して無いので時間を見て試してみます。
> 結果ですがクリアはされているようでした。

「Redirectすべきは更新時ではなくその手前の処理時です。」とは「ボタンのイベントではなくPage_Loadイベント」あるいは「更新を押したときではなく実際にボタンを押したとき」という意味ですか。
こちらのやり方が違うのか、納得できません。
リクエストが同じ&IsPostBackが両方ともtrueとなれば、サーバー側で情報を保持しておいて検証するしか手がないように思えます。

引用返信 編集キー/
■5652 / inTopicNo.12)  Re[10]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ mあ (21回)-(2007/07/19(Thu) 15:19:39)
No5643 (ghost_shell さん) に返信
> ■No5581 (黒龍 さん) に返信
> 「Redirectすべきは更新時ではなくその手前の処理時です。」とは「ボタンのイベントではなくPage_Loadイベント」あるいは「更新を押したときではなく実際にボタンを押したとき」という意味ですか。
> こちらのやり方が違うのか、納得できません。

再送信要求が発生するタイミングは、ブラウザツールバーの「↑↓」更新
ボタンを押したときですよね。

このタイミングによりサーバーへ送られる内容は、今の画面のひとつ前の
画面の内容ですよね。

てことは、ひとつ前の画面がリロードすれば、今再送信しようとしている
フォームパラメータはリセットされるので「再送信しますか?」のダイア
ログが出ない「↑↓」更新ボタンが押せる、という訳です。

と解釈しました。

GETでの簡易版ですが、これと同じ機構を実装するだけだと思います。
再送信しようとしてます、画面はあいにく出ません。

<script>
<!--//
var request = location.search.split("?");
window.onload = function () {
reloadTest();
}
function reloadTest() {
if (request.length == 2) {
location.replace(location.href.split("?")[0]);
}
}

//-->
</script>
<form method="GET">
<input type=text name=A>
<input type=checkbox name=C1 id=C1><label for=C1>チェック1</label>
<input type=checkbox name=C2 id=C2><label for=C2>チェック2</label>
<input type=checkbox name=C3 id=C3><label for=C3>チェック3</label>

<input type=submit>
</form>

POST だったら、リクエストパラメータはブラウザ自身が保持するため、
上記のように、判定材料がURL取れないのですけど、POSTアクション契機
のボタンの時はリロードする仕掛けを展開して返す、みたいな仕掛けを
サーバー側に用意しておけばいいだけの話ですので。

ASPのRedirectはもっと効率良いのかもしれませんが。たぶん、
HTTPヘッダのリロードだと思います。


引用返信 編集キー/
■5664 / inTopicNo.13)  Re[11]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ Jitta (374回)-(2007/07/19(Thu) 20:05:56)
えと、サーバー側に、クライアントへレスポンスを返す直前に発生するイベントがあるので、そこで
1.response.redirect
2.ヘッダーをいじる
3.スクリプトを埋める

といった方法が簡単かと思います。



ただ、戻ると、再送できてしまいます。
再送対策なら、当然戻るにも対応が必要かと思います。
引用返信 編集キー/
■5677 / inTopicNo.14)  Re[12]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ mあ (23回)-(2007/07/20(Fri) 10:20:59)
2007/07/20(Fri) 10:30:51 編集(投稿者)
2007/07/20(Fri) 10:30:45 編集(投稿者)

No5664 (Jitta さん) に返信
> えと、サーバー側に、クライアントへレスポンスを返す直前に発生するイベントがあるので、そこで
> 1.response.redirect
> 2.ヘッダーをいじる
> 3.スクリプトを埋める
>
> といった方法が簡単かと思います。
>
>
>
> ただ、戻ると、再送できてしまいます。
> 再送対策なら、当然戻るにも対応が必要かと思います。

今までは、IE に限り、
<body oncontextmenu="return false;"> と ツールバー無しの別窓起動、
親画面のバグ利用の window.opener = null;self.window.close(); で
戻れない画面(ファンクションキーは別途スクリプトでハンドリング、
できたか?覚えが無い・・・)が出来たのですけど、画面省スペース化
のあおりでタブブラウザが普及しそうなので、「戻る」ボタンへの対応
は面倒になりますね。


http://www.javable.jp/notes/webscripts/backbutton.html

<html>
<script>
<!--
history.forward();

var arr = location.search.split("?");
if (arr.length < 2) {
//
}
else {
document.write("<p style='font-size:20px;'>" + arr[1] + "</p>");
}
//-->
</script>
<body>
<form action="2.html">
<input type=text name=T1><input type=submit>
</form>
</body>
</html>

NGでした。

引用返信 編集キー/
■5928 / inTopicNo.15)  Re[13]: ブラウザによる更新(再送信)のイベント発生の仕組みと対処
□投稿者/ ghost_shell (6回)-(2007/07/26(Thu) 13:14:14)
ghost_shell さんの Web サイト
すいません。返信が遅くなりました。

>えと、サーバー側に、クライアントへレスポンスを返す直前に発生するイベントがあるので、そこで

Page_PreRenderもしくはPage_Unloadですか。
赤間さんの本で読んだ気がしたのですが、ちょっと見つけられないのでwebページで(知りたい方用)

http://support.microsoft.com/kb/305141/ja


解決策を導き出すには、HttpResponseクラスやPageクラスのプロパティを地道に調べていくのが一番ですかね。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -