web-dev-qa-db-ja.com

jQueryajaxで変更されていない304を処理する適切な方法

JQuery 1.5以降、ajaxメソッドは、XMLHTTPRequestのW3C仕様に従って、success()ハンドラーを呼び出すことにより、304の変更されていない応答を正しく処理するようになりました。これにより、サーバーが実際にデータを返さなかった場合でも(最新のデータが既にキャッシュされているため)、アプリケーションは要求を成功したものとして扱うことができます。

通常の(キャッシュされていない)GET要求の場合、成功ハンドラーは次の引数で呼び出されます。

  • データ:{サーバーからのデータ}
  • ステータス:OK
  • jqXHR:
    • ステータス:200
    • statusText:OK
    • responseText:{サーバーからのデータ}

キャッシュされたGETリクエストの場合、成功ハンドラーは次の引数で呼び出されます。

  • データ:未定義
  • ステータス:変更なし
  • jqXHR:
    • ステータス:304
    • statusText:変更されていません
    • responseText:{キャッシュからのデータ}

(少なくとも、マニフェストファイルを介してアプリケーションキャッシュを使用するWebアプリの場合、これはIOS 4.2で返される方法です。これは、上の一般的なブラウザーキャッシュで一貫していると思います。ほとんどのプラットフォーム/ブラウザ)。

「data」引数は、リクエストが200OKの場合にのみ入力されることがわかります。一方、jqXHR.responseTextには、データがサーバーからのものか(200 OK)からのものか、キャッシュからのものか(304 Not Modified)に関係なく、常にデータが入力されます。

ほとんどのGETリクエストでは、成功ハンドラーは、データがどこから来たかに関係なく、取得したデータを使用して何かを実行したいので、成功コードが常にjqXHR.responseTextを使用するのが最も理にかなっているようです。このようなことをするのではなく:

if ("notmodified" === status) {
  // do something with jqXHR.responseText
} else {
  // do something with data
}

または、jqXHR.responseText would n'tが成功ハンドラーに入力されているが、データarg wouldの場合はありますか?

コードベースを調べて、すべての成功ハンドラーを変更する必要があります(以前は、キャッシュからでも常にデータを返すjQuery 1.4.2を使用していました)。だから私はそれを正しい方法で扱っていることを確認したいだけです。 (最後までやりたくなくて、別の方法でやるべきだったことに気づかないでください)。

18
Scott

質問に明らかな欠陥があることに気づきました。データは常にテキストであると想定していたため、データ引数よりもjqXHR.responseTextを使用するのが理にかなっています。

ただし、dataTypeがJSON、JSONP、スクリプトなどの場合、304 Not Modified応答で返されたデータが未定義として返される場合は、最初にjqXHR.responseTextを文字列から目的の型に変換する必要があります。 、例えば。

if (data === undefined) {
  data = $.parseJSON(jqXHR.responseText);
}

...そして、本当に必要な場合にのみ、この(潜在的に高価な)変換を実行したいと思うでしょう。

ちょっと考えてみると、今では理にかなっています...データは常にサーバーから戻ってきたものになります(場合によってはnot 304では未定義です...例:サーバー追加のtext/htmlを返す可能性があります);これにより、開発者は304の場合に何をしたいかを柔軟に選択できます。

  • サーバーからの応答を表示します(存在する場合)
  • JqXHR.responseTextを使用します
  • 完全に何か他のことをしてください...
7
Scott

コンテキストに応じて、ajaxリクエストにcacheパラメーターを使用できます。

$.ajax({
    url: ".....",
    dataType: "json",
    type: "GET",
        cache: false,
    contentType: "application/json",
        success: function (data, textStatus) {
            console.log("RECV: " + data);
        }
    });

それは私のために働いています。

5
David N. Welton