web-dev-qa-db-ja.com

[戻る]ボタンと[更新]ボタンがフォームを再送信しないようにするにはどうすればよいですか?

私はウェブ開発をしています。

クレジットカードに関するページがあります。ユーザーが[更新]または[戻る]をクリックすると、トランザクションがもう一度実行されますが、これは望ましくありません。

これには、ブラウザの左上の「戻る」と「更新」ボタン、「右クリック->更新/戻る」が含まれ、「F5」キーを押します。これは、すべてではなく特定のcgiページでのみ行われます。

これはJavascriptを使用して実行できますか?または他の方法?

24
sytee

標準的な方法 は、3つのステップで実行します。

  1. フォームページはフィールドを処理ページに送信します
  2. 処理ページはデータを処理し、結果ページにリダイレクトします
  3. 結果ページは結果を表示するだけで、リロードしても害はありません。
49
vartec

これは、基本的なブラウザーのユーザーエクスペリエンスモデルに違反します。ユーザーは常にブラウザーの[更新]ボタンと[戻る]ボタンを使用できる必要があります。別の方法でページを修正することをお勧めします。

質問を更新して、使用しているサーバーの言語/プラットフォーム/テクノロジーを含めると、誰かが解決策を提案できる可能性があります。

12
Richard Ev

フォームを再送信すると重複したトランザクションが生成されるという単純な事実が心配されています。フォームデータの各送信が一意であることを確認するには、何らかのチェックが必要です。

たとえば、フォームを送信するページには、フォームとともに送信される一意のIDを指定する必要があります。次に、ビジネスロジックは、送信されたフォームが既に処理されていることを認識できるはずです(一意のIDは同じではなくなります)。そのため、2回目の試行は無視されます。

「標準的な方法」でも、クライアントが[戻る]ボタンを2回クリックすること、または(何らかの理由で)フォームが処理されたと思わない場合は、戻ってフォームを再送信することはできます。

8
James Camfield
  1. ランダムな文字列を生成してセッションに保存し、

  2. それを隠し値としてフォームに出力し、

  3. 送信された変数とストア変数を確認し、一致がリクエストを処理する場合、

  4. 1に移動します。

5
Anonymous

このコードをフォームページに配置します

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Response.Cache.SetExpires(DateTime.Now-new TimeSpan(1,0,0));

Response.Cache.SetLastModified(DateTime.Now);

Response.Cache.SetAllowResponseInBrowserHistory(false);
3
Zoomer

これらのアクションを「ブロック」しないでください。あなたがすべきことは、誰かがフォームを「二重に送信」しても何も起こらないことを確認することです。

2
andi

一部のブラウザではそれさえできません。これは良いことです!

1
Tobias

最善の方法は、2回目(以降)の試行を「これは単なる再送信です」と認識して無視できる十分なセッション処理ロジックを用意することです。

1
Vatine

ここでは見ていなかったので、ここにあります。

  1. フォームに一意のトークンを入力します。
  2. 送信ボタンは、サーバーへのxmlhttp(ajax)要求をトリガーして、保存された値が1のトークンにちなんで名前が付けられたセッション変数を作成します。
  3. Ajaxリクエストは、肯定的な状態変化を受け取った後にフォームを送信します。
  4. フォーム処理スクリプトは、格納された値1を使用してセッション変数をチェックします。
  5. スクリプトはセッション変数を削除し、フォームを処理します。

セッション変数が見つからない場合、フォームは処理されません。変数が見つかるとすぐに削除されるため、フォームは送信ボタンを押すことによってのみ実行できます。更新して戻ると、フォームは送信されません。これはリダイレクトを使用しなくても機能します。

1
Malcolm Cooper

上記のPost/Redirect/Getの説明は少しあいまいです

これが私がフォローしたものであり、うまくいけばそれは将来の誰かを助ける

http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html

基本的に、上記のソリューションに基づくプロセスは次のとおりです。

  1. FORMページから処理ページ(またはそれ自体)に送信する
  2. データベースまたは支払い処理などを処理する
  3. 必要に応じて、ユーザーのフィードバックメッセージをセッション変数、考えられるエラーメッセージなどに保存します
  4. 結果ページ(または元のフォームページ)へのヘッダーリダイレクトを実行します。 必要に応じて、処理ページからカスタムメッセージを表示します。 「エラークレジットカードの支払いが拒否されました」など、セッション変数をリセットします。

次のようなものでリダイレクト:

header("HTTP/1.1 303 See Other");
header("Location: http://$_SERVER[HTTP_Host]/yourfilehere.php");
die();

ヘッダーリダイレクトは、「yourfilehere.php」でGETリクエストを開始します。リダイレクトは、サーバーからデータをフェッチする「リクエスト」であり、データを送信するPOSTではないためですサーバー。したがって、redirect/GETは、更新後に発生するそれ以上のDB /支払い処理を防ぎます。 301エラーステータスは、戻るボタンを押すのに役立ちます。

参考資料:

  1. http://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
  2. http://www.theserverside.com/news/1365146/Redirect-After-Post
  3. http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
  4. https://en.wikipedia.org/wiki/HTTP#Request_methods
  5. http://en.wikipedia.org/wiki/Post/Redirect/Get
0
wired00

vartec:sソリューションは、reback-problemを解決します。back-problemは解決しません。そのためのソリューションを次に示します。

  1. フォームページは、セッション変数を設定します。例:session( "fromformpage")= 1
  2. 処理中のページはセッション変数をチェックし、「1」の場合はデータを処理し、「1」以外の場合は結果ページにリダイレクトし、結果ページにリダイレクトします。
  3. 結果ページはセッション変数を ""に設定します。

次に、ユーザーが戻るボタンを押している場合、処理ページは処理を再度実行せず、処理ページにリダイレクトするだけです。

0
Stefan

このjavascriptをaspxページのhtmlセクションのヘッドセクションの上に置くだけです

<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>

ユーザーが戻るボタンを押してアクセスできないようにするページのhtmlセクションに配置する必要があります

ページの完全なコードは次のようになります

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>
</head>
<body onload="disableBackButton()">
<form id="form1" runat="server">
<div>
This is First page <br />
<br />
Go to Second page
<br />
<br />
<asp:LinkButton ID="LinkButton1" runat="server"
PostBackUrl="~/Default2.aspx">Go to Second Page
</asp:LinkButton></div>
</form>
</body>
</html>

Firefoxを使用している場合は、onloadの代わりに使用してください

aspxページのコードビハインドを使用して[戻る]ボタンを無効にしたい場合は、以下のコードC#コードビハインドを記述する必要があります

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string strDisAbleBackButton;
strDisAbleBackButton = "<script language="javascript">\n";
strDisAbleBackButton += "window.history.forward(1);\n";
strDisAbleBackButton += "\n</script>";
ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "clientScript", strDisAbleBackButton);
} 

Page_loadイベントまたはPage_Initイベントのいずれかにこのコード行を書き込むことにより、ブラウザーのキャッシュまたはキャッシュを無効にすることでも、これを実現できます

protected void Page_Init(object Sender, EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
Response.Cache.SetNoStore();
}

これを行うと、ユーザーはブラウザの戻るボタンを押すとページが期限切れになったというメッセージを受け取ります

デモは:

enter image description here

0

このコードは、現在のページmeから戻らないように機能します。

ここで、コンテキストメニューを開かずにブラウザのリロード時にページを離れるかどうかを尋ねるのに役立つコードを配置します...

私はブラウザの戻るボタンをクリックして質問しようとしています

jQuery( document ).ready(function() {

    document.onkeydown = fkey;
    document.onkeypress = fkey
    document.onkeyup = fkey;

    var wasPressed = false;

    function fkey(e){
        e = e || window.event;
        //alert(e.keyCode);
        if( wasPressed ) return; 


        if (e.keyCode == 116 || e.keyCode == 8 || e.keyCode == 17) {
                     // alert("f5 pressed");
                      window.onbeforeunload = null;
                      return true;
                 }

    }
window.onbeforeunload = function (event) {
    var message = ''; // Type message here

    if (typeof event == 'undefined') {
        event = window.event;
    }
    if (event) {
        event.returnValue = message;
    }

    return message;
};

jQuery(function () {

    jQuery("a").click(function () {
        window.onbeforeunload = null;
    });

    jQuery(".btn").click(function () {
        window.onbeforeunload = null;
    });

    //Disable part of page
    $(document).on("contextmenu",function(e){
        return false;
    });
});});

おかげで、

0
Bhavin Patel