0

ユーザーが選択した行のリストがあり、それらを1つずつ削除して、最後に結果を表示したい。

明らかに、単純なループを実行して毎回 ajax 関数を呼び出すだけの場合、どのようにループして、どれが成功し、どれが失敗し、それらがすべて完了したかを確認するにはどうすればよいですか?

どのようにしますか?一括編集/削除を行う適切な方法は何ですか?

4

1 に答える 1

9

各 ajax リクエストには、関連するオーバーヘッドがあります。サーバーがリクエストで過負荷になる可能性があり、十分なトラフィックを受信した場合にDoSを行う可能性があるため、各行に対して呼び出しを行うことはお勧めできません。また、すべてのブラウザーには、一度に作成できる HTTP 要求の数に制限があるため、(ブラウザーによっては) 次々に実行するように指示したとしても、削除は一度にではなくバーストで行われます。

最良のオプションは、編集/削除する行を JSON 配列にグループ化し、それらを単一の要求でサーバーに送信することです。その後、サーバーで JSON を解析し、それに応じてアイテムを削除できます。終了したら、結果を含む JSON 配列を返します。

この jQuery 疑似コード コードは、ネイティブJSON オブジェクトを使用してブラウザーをターゲットにするか、またはjson2.jsを使用していることを前提としています。基本的に、このコードは、ユーザーに表示するテーブルの各行で「隠し ID」フィールドを検索し、それを配列に追加するだけです。これは、必要に応じて調整できます。

var recordsToDelete = [];
$("tr.myRow").each(function() {
    var id = $(this).find("input:hidden").val();
    recordsToDelete.push(id);
});
var json = JSON.stringify(recordsToDelete);

結果に対処するのは難しい場合があります。(成功した場合) すべての行が削除されるように、システムを設計する必要があります。非常に複雑なシステムを扱っている場合を除き、一部の行が成功し、一部の行が失敗するという状況は決して発生しないはずです。これが発生した場合は、システム アーキテクチャを再検討する必要があります。jQuery には、リクエストの一般的な成功または失敗に対処するために使用できるおよびのイベントがあります。使用することをお勧めします。successfailure

上記のコードに引き続き、これはレコードの削除を処理する 1 つの方法です。completeここでは単純化のためにイベントを使用していますが、可能であればsuccessおよびイベントを使用する必要があります。リクエストが成功するか失敗するかに関係なく、イベントは常に発生しますfailurecomplete

$.ajax({
    url: "http://stackoverflow.com/questions/1653127",        
    type: "POST", // Always use POST when deleting data
    data: { ids: json },
    complete: function(xhr, status) {
        var response = JSON.parse(xhr.responseXML);
        // Response will be an array of key/value
        // pairs indicating which rows succeeded or failed
        for (var i = 0; i < response.length; i++) {
            var recordID = response[i].recordID;
            var status = response[i].status;
            // Do stuff with the status codes here
        }
    }
});

コメントへの対応:

  • gmail のようなアプリの場合、その仕組みは非常に複雑であるため、「Google がこのようにするので、私もこのようにします」と言うのは得策ではありません。Google で機能するすべての機能が、すべての企業や Web サイトで機能するわけではありません。Google のような企業には、対処すべき問題があり、他の Web サイトが心配する必要はほとんどありません。しかし、あなたの質問に答えるために
    • これを確認したところ、GMail は ID の配列を持つ 1 つの AJAX リクエストを使用します。個別のステータス コードは返されません。どうやら (私はここで推測しています)、Gmail は実行したアクションの「アクション ID」を返すようです。そのため、メールを削除した直後に表示される元に戻すリンクをクリックすることで、そのアクションを元に戻すことができます。
    • アプリで作業するときは、通常、操作が失敗しないように十分な信頼性を確保する必要があります。これを確認するには、厳密な QA を実行する必要があります。基本的に、削除操作は全体として成功または失敗する必要があります。これが発生する可能性のあるシナリオは、サーバーがダウンしたときにユーザーが削除をクリックした場合です。ユーザーにとっては、ページをリロードしていないためサイトはまだ稼働していますが、AJAX 要求はどこにも移動できないため失敗します。このようなものを処理したいと思うでしょう。
    • これは、アプリのビジネス ルールに大きく依存します。複数のユーザーが同時にレコードを変更できる状況でアプリケーションが使用されている場合 (単なる例)、あるユーザーが削除しようとしたものは、その "削除" ボタンをクリックする直前に他の誰かによって削除された可能性があります。ほとんどの場合、誰が最初にレコードを削除したかを気にかけている人は見当たりません。ただし、ビジネス ルールによって、この情報をユーザーに報告する必要があることが (ばかげているかもしれませんが) 規定されている場合があります。この場合、削除ごとにステータスの配列を返す必要があります。
  • ハッカーが他の人の記録を削除するのを防ぐには、いくつかのことを行う必要があります。
    • AJAX ハンドラーをサイトの他の部分と同じように扱います。彼らは特別な特権を得るべきではありません。AJAX ハンドラーへの要求は、他のすべてと同様に認証される必要があります。
    • 破壊的な操作やデータを変更する操作には、POST 要求 (私の例で述べたように) を使用します。これにより、ハッカーがクロスサイト リクエスト フォージェリ (CSRF)を実行することが難しくなります。明らかに、これは簡単にできることではありませんが、簡単なエクスプロイトを阻止します。
    • 明らかに、ユーザーが削除要求を送信したからといって、ユーザーがレコードを削除する権利を持っていると思い込まないでください。削除を実行するユーザーが各レコードを削除する権限を持っていることを確認してください。これを行う方法は、サーバー側のアプリケーションによって異なります。
    • クライアントからサーバーに送信されるすべての値を必ずエンコードしてください。これにより、SQL インジェクションが防止されます。
    • OWASP のトップ 10 リストに精通していることを確認してください。Web サイトで最も一般的な (しかしすべてではない) 主要なエクスプロイトを取り上げ、それらの被害に遭わないようにする方法を説明します。
于 2009-10-31T02:19:52.530 に答える