9

この問題はバックボーンやJavaScriptとは関係がありませんが、問題のコンテキストとしてバックボーン・コードを含める必要があります。バック・ボタンをクリックしたときにキャッシュから直接応答が返される

関連のコード

私はcontactIdと呼ばれるパラメータを取るルートにclient-side Backbone routerを持っています。これは次のようになります。

Backbone.Router.extend({ 

    routes: { 
    "jobs/new?contact_id=:contactId": "newForContact" 
    }, 

    // Fetch the contact and initialize a new job model which 
    // is associated with that contact. 
    newForContact: function(contactId) { 
    var contact = new Contact(id: contactId); 
    contact.fetch({ 
     success: _.bind(function(model, resp) { 
     var job = new Job(contact: contact); 
     this.new(job); 
     } 
    }, this)); 
    }, 

    // Show the JobView for the given job. 
    new: function(jobModel) { 
    view = new JobView(job: jobModel); 
    $('body').append(view.render().el); 
    } 
}; 

pushStateをオンにしてこの設定を使用しようとしています。

newForContactルートをトリガーするルートにヒットすると、すべて正常に動作します。ただし、この時点でブラウザの戻るボタンを押すと、ブラウザのキャッシュから直接contact.fetch()メソッドのJSON応答が返されます。要求はサーバーに送信されません。

fetch JSON response

アプリケーションログ

あなたはRailsのアプリのログでこれを見ることができます。この部分では、私はnewForContactをトリガーするルートにアクセスします。

Started GET "/jobs/new?contact%5Bid%5D=1&contact%5Btype%5D=Customer" for 127.0.0.1 at 2012-10-31 22:41:48 +0000 
Processing by JobsController#new as HTML 
    Parameters: {"contact"=>{"id"=>"1", "type"=>"Customer"}} 
    User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 
    Business Load (0.3ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" IN (1) 
    Rendered shared/_search_form.html.erb (0.3ms) 
    Job Load (0.4ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."business_id" = 1 ORDER BY created_at desc 
    Rendered jobs/_list.html.erb (1.5ms) 
    Rendered jobs/index.html.erb within layouts/application (4.1ms) 
    Rendered layouts/_head_content.html.erb (0.7ms) 
    Rendered layouts/_flash.html.erb (0.0ms) 
Cache read: views/jobs/main_nav/d6a805d9b6f285e424f207add4f35595 
Read fragment views/jobs/main_nav/d6a805d9b6f285e424f207add4f35595 (0.4ms) 
    Rendered layouts/_nav.html.erb (0.6ms) 
    Rendered layouts/_header.html.erb (0.7ms) 
Completed 200 OK in 12ms (Views: 8.0ms | ActiveRecord: 1.0ms) 
Cache read: http://print.dev/customers/1? 

この時点で、JSONリクエストで連絡先を取得することがわかります。

Started GET "/customers/1" for 127.0.0.1 at 2012-10-31 22:41:48 +0000 
Processing by CustomersController#show as JSON 
    Parameters: {"id"=>"1"} 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 
    Business Load (0.4ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" IN (1) 
    Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."business_id" = 1 AND "customers"."id" = $1 LIMIT 1 [["id", "1"]] 
    CustomerEmployee Load (0.3ms) SELECT "customer_employees".* FROM "customer_employees" WHERE "customer_employees"."employer_id" IN (1) 
    Job Load (0.4ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."contact_type" = 'Customer' AND "jobs"."contact_id" IN (1) 
    Invoice Load (0.3ms) SELECT "invoices".* FROM "invoices" WHERE "invoices"."client_id" IN (1) 
    Job Load (0.5ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."contact_id" = 1 AND "jobs"."contact_type" = 'Customer' AND "jobs"."state" = 'finished' AND "jobs"."invoice_id" IS NULL 
    Rendered customers/show.json.rabl (2.8ms) 
Completed 200 OK in 67ms (Views: 3.2ms | ActiveRecord: 2.5ms) 

この時点で、ブラウザの[戻る]ボタンを押しますが、サーバーに新しい要求は記録されません。

Railsの環境

これは私のステージングサーバー(Heroku)ではなく、開発中に発生します。私はレール設定でキャッシングがオンになっているステージング環境でPowのアプリを実行することで、ローカルで再作成できます。

config.action_controller.perform_caching = true 

キャッシングをオンにしても、開発環境でバグを再作成できないことに注意してください。

この問題はChrome 22.0.1229.94,FF 16.0.2およびSafari 6.0.1に発生します。私はRails 3.2.8を使用しています。

おそらく関連の質問

It seems like this guy was having a very similar problem to me.

ライブサンプル

あなたが本当にあなたにしたい場合はHerokuの上で私のステージングサーバーに住んで問題を表示することができます。

手順をRepro()編集:これらは問題を修正してからもう機能しません。[email protected]とパス:メールでhere

  1. ログイン
  2. foobarに訪問http://print-staging.herokuapp.com/customers/2。あなたは見た目に見えないダイアログボックスを開いているはずです。
  3. ダイアログの小さな「新規ジョブ」リンクをクリックします。ページが変更され、新しいダイアログが開きます。
  4. ブラウザの戻るボタンをクリックします。

答えて

9

あなたは、これは応答をキャッシュしないようにブラウザに指示する必要があり、サーバー側であなたの応答をキャッシュなしのヘッダーを追加することができます。

response.headers["Cache-Control"] = "no-cache" 
+1

しかし、どうして私はそれをしなければなりませんか?私は実際にはブラウザがほとんどの時間(おそらくそれほど変化しないでしょう)の応答をキャッシュしたいと思っています。私はちょうど私がキャッシュされた応答を私に示すために戻るボタンを望んでいない。基本的にはJSONリクエストを送信したいと思いますが、ユーザーが「戻る」ボタンを押すと、JSONリクエストではなくHTMLリクエストを行いたいと思います。 –

+0

申し訳ありませんが、Davidの意味を理解できません。どのようにキャッシュを使用したいのですが、キャッシュされたレスポンスをバックボタンに表示させたくないのですか? – kabaros

+0

私はJSON GET要求をブラウザヒストリスタックに入れないようにする方法が必要だと思います(バックボーンで 'pushState'を使っているにもかかわらず)バックボタンを押してスキップしますJSONリクエストを介して、その前にリクエストを表示することができます(これはHTMLリクエストが実際のページを形成してユーザを表示できるはずです)。おそらくこれは不可能です、わかりません? –

2

私はバックボーンを使用していない、これはちょうど私がAJAX/pushstate


で行っている私は私のAJAX応答でhistory.pushState()を使用しています。

var url = "http://foo.com/path/to/page"; 
var relative_url = UrlToRelative(url); // some function to convert a URL to relative 
var absolute_url = UrlToAbsolute(url); // some function to convert a URL to absolute 
history.pushState(
    { 
    hash: "#"+relative_url, 
    title: document.title, 
    initialHref: absolute_url 
    }, 
    document.title, 
    url 
); 

そして私はonPopStateのイベントリスナーを持っている:

window.onpopstate = function(event) { 
    if (event.state && event.state.initialHref) { 
    $.ajax({ 
     complete: null, 
     data: {}, 
     dataType: "script", 
     success: null, 
     type: 'GET', 
     url: event.state.initialHref 
    }); 
    } 
} 

このイベントリスナーは、AJAX要求を行います。唯一の問題は、サーバーへの応答を得るのに数秒かかるページに戻るときに、画面が数秒で変化することです。スピナーやビジー状態のインジケーターはありません。

関連する問題