0

jQueryを使用して(javascriptが有効になっている場合)投稿するプログラム拡張フォームがあります。

JavaScript を無効にすると、すべて正常に動作します。

<form class="clearfix" action="https://examples.com/api/rest/members/memberidnotshownforsecurity/examples/?on_success=https://examples.com/account/examples?alerts=inserted&amp;on_failure=https://examples.com/error" method="POST" onsubmit="return false;">
    <input id="url" type="text" name="example_url" placeholder="paste a link to example it"><br>
    <button id="insertExample" type="button">create</button>
</form>

#insertExample ボタンをクリックすると、jQuery がリクエストを処理します。

<script type="text/javascript">
    $(document).ready(function() {
        var insertExampleMutex = false;
        $("#insertExample").on('click', null, function(event) {
            if ( insertExampleMutex == false ) {
                insertExampleMutex = true;
                var reference = $(this);
                var progsubmit = reference;
                var progform = progsubmit.parents('form');
                var progmethod = progform.attr('method');
                var progaction = progform.attr('action').substring( 0, progform.attr('action').indexOf('?') );
                var progdata = progform.serialize();
                var inventory = reference.parents('#core').find('#inventory');
                progsubmit.html('loading...');
                $.ajax({
                    type: progmethod,
                    url: progaction,
                    data: progdata,
                    dataType: 'json'
                }).done(function(data) {
                    if ( data.status == '1' ) {
                        inventory.prepend('<div style="cursor: pointer;" id="selectExample" href="' + "https://examples.com" + '/api/rest/members/' + data['data']['member_examples']['member_id'] + '/examples/' + data['data']['member_examples']['example_id'] + '" class="alert bgsuccess"><center><p class="psmall">A new example was created. Click to here display.</p></center></div>');
                    } else {
                        inventory.prepend('<div style="cursor: pointer;" onclick="window.location.reload();" class="alert bgfailure"><center><p class="psmall">An error occurred.</p></center></div>');
                    }
                }).fail(function() {
                    inventory.prepend('<div style="cursor: pointer;" onclick="window.location.reload();" class="alert bgfailure"><center><p class="psmall">An error occurred.</p></center></div>');
                }).always(function() {
                    progform[0].reset();
                    progsubmit.html('create');
                    inventory.children('p').remove();
                    insertExampleMutex = false;
                });
            }
        });
    });
</script>

問題は、投稿が成功したにもかかわらず、.failure() リクエスト ハンドラーがトリガーされることです。2つ目の問題は、1回だけでなく2回も成功することです。

もちろん、IDを除いて、同一のデータを持つ2つのエントリがデータベースに作成されます。

少し検索しましたが、決定的なものは見つかりませんでした。

  • 複数のリクエストを無視するミューテックス変数を既に使用しています。

  • フォームはブラウザと JavaScript によって送信されていません。どちらも ajax 呼び出しに由来します (ミューテックス変数のために不可能と思われます)。

  • Ajax が 301 を取得している可能性があることを読みました。これにより、リダイレクトされた URL に再度投稿される可能性がありますが、そうではないようです。

4

1 に答える 1

1

私の経験では、サーバーからの正常な応答を処理する JavaScript が失敗すると、失敗ハンドラーが起動します。つまり、サーバーは成功する可能性がありますが、クライアントが正しく処理できない場合、エラー イベントがトリガーされます。chrome や firebug などを使用して、応答で起動する JavaScript のデバッグを試みることができます。

$(document).ready 関数が複数回起動すると、ダブルヒットの問題が発生しました。たとえば、投稿したスクリプト ブロックが複数回含まれる HTML にある場合、コードが複数回接続される原因となります。

ここでも、document.ready 関数にブレークポイントを設定して、何が起こっているかを確認できます。

于 2013-04-09T02:39:08.190 に答える