请注意,我不认为此问题与Backbone或JavaScript有关,但有必要在问题中包含一些Backbone代码作为上下文。
相关代码
我有一个client-side Backbone router,其路线带有一个名为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响应。没有请求发送到服务器。
应用程序日志
您可以在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的应用程序在本地重新创建它,该环境在rails配置中打开了缓存。
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的步骤(编辑:这些因为我修补了问题后不再起作用了。)
答案 0 :(得分:10)
您可以在服务器端向响应添加no-cache标头,这应该指示浏览器不缓存响应:
response.headers["Cache-Control"] = "no-cache"
答案 1 :(得分:2)
我没有使用Backbone,这正是我用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请求。唯一的问题是,当返回到需要几秒钟才能获得服务器响应的页面时,屏幕需要几秒钟才能更改。并且没有微调或繁忙的进度指示器。