10

この問題がバックボーンや JavaScript に関連しているとは思わないが、問題のコンテキストとしてバックボーン コードを含める必要があることに注意してください。

関連コード

と呼ばれるパラメータを取るルートを持つクライアント側のバックボーン ルーターcontactIdがあります。これは次のようになります。

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 応答がブラウザーのキャッシュから直接提供されます。サーバーにリクエストは送信されません。

JSON レスポンスを取得する

アプリのログ

これは、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 ) でのみ発生します。Rails構成でキャッシュがオンになっているステージング環境でPowを使用してアプリを実行することにより、ローカルで再作成できます。

config.action_controller.perform_caching = true

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

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

おそらく関連する質問

この男は私と非常によく似た問題を抱えていたようです。

ライブサンプル

本当に必要な場合は、Heroku のステージング サーバーで問題をライブで表示できます。

再現手順 (編集:問題にパッチを当てたので、これらは機能しなくなりました)。

  1. ここからメールでログイン: user@example.com と pass: foobar
  2. http://print-staging.herokuapp.com/customers/2にアクセスしてください。めちゃめちゃなダイアログ ボックスが表示されるはずです。
  3. ダイアログの小さな「新しいジョブ」リンクをクリックします。ページが変更され、新しいダイアログが開きます。
  4. ブラウザの戻るボタンをクリックします。
4

2 に答える 2

10

サーバー側でレスポンスに no-cache ヘッダーを追加できます。これにより、ブラウザはレスポンスをキャッシュしないように指示されます。

response.headers["Cache-Control"] = "no-cache"
于 2012-10-31T23:18:13.470 に答える
2

私はバックボーンを使用していません。これは私が AJAX / pushstate で行ったことです。


history.pushState()AJAX 応答で使用します。

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 要求を行います。唯一の問題は、サーバーの応答を取得するのに数秒かかるページに戻るときに、画面が変わるのに数秒かかることです。また、スピナーやビジー プログレス インジケーターはありません。

于 2012-11-06T18:09:34.410 に答える