使用“后退”按钮时,Rails 3.1将返回原始Javascript代码 我的基本目标

使用“后退”按钮时,Rails 3.1将返回原始Javascript代码 我的基本目标,javascript,jquery,ajax,ruby-on-rails-3.1,Javascript,Jquery,Ajax,Ruby On Rails 3.1,Rails应用程序,可以通过Ajax加载新内容,同时使用HTML5维护浏览器的历史状态。我一直在追赫罗库。我还进行了设置,以便可以更详细地查看下面提到的所有代码 问题 我使用HTML5浏览器历史API成功地实现了基本应用程序(有一次我还使用history.js jQuery插件制作了一个版本)。一切正常,直到用户单击非ajax链接,然后单击后退按钮。例如,如果用户单击项目2,则应用程序将成功加载新内容并更改浏览器状态。如果他们点击后退按钮,它也会正确地重新加载以前的内容,并将浏览器状态更改回匹配

Rails应用程序,可以通过Ajax加载新内容,同时使用HTML5维护浏览器的历史状态。我一直在追赫罗库。我还进行了设置,以便可以更详细地查看下面提到的所有代码

问题 我使用HTML5浏览器历史API成功地实现了基本应用程序(有一次我还使用history.js jQuery插件制作了一个版本)。一切正常,直到用户单击非ajax链接,然后单击后退按钮。例如,如果用户单击项目2,则应用程序将成功加载新内容并更改浏览器状态。如果他们点击后退按钮,它也会正确地重新加载以前的内容,并将浏览器状态更改回匹配状态。但是如果用户浏览到另一个网页(互联网上的任何其他网页),然后单击浏览器的后退按钮,Rails应用程序将呈现原始javascript而不是原始页面

直到最后一步,当控制器开始从show.js.erb而不是show.html.erb返回原始javascript时,一切都正常工作。我尝试过在控制器中更改几个设置,但我无法找出具体原因。我确实知道,如果我删除show.js.erb中的history.pushState调用,问题就会停止(尽管很明显,我失去了最初寻找的所有浏览器历史记录功能)

有什么想法吗

奖励:令人痛苦的细节 这就是它的工作原理(我想!)

用户单击一个链接,该链接在引擎盖下如下所示:

<%= link_to number_to_human(volume.number), volume_path(volume), :remote => true %>
这会将请求传递给show.js.erb,如下所示:

def show
  @volume = Volume.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.js # show.js.erb
    format.json { render json: @volume }
  end
end
var stateObject = {"html": "<%= escape_javascript render(@volume) %>"};
history.pushState(stateObject,'',"<%= escape_javascript volume_path(@volume) %>");
$('#volumes').fadeTo(0, 0);
$('#volumes').html(stateObject.html).fadeTo('slow', 1.0);

我对RoR很陌生,所以我不确定我的答案是否是最好的,但我遇到了同样的问题并设法解决了它。这是我的两分钱

显示原始ajax响应的原因似乎是浏览器缓存。我通过添加以下标头来防止响应被缓存,从而修复了该问题

response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"

Joon上面所说的肯定奏效了。在添加标题之前,我只是添加了一个额外的检查,以查看请求是否来自ajax。谢谢Joon

if request.xhr?
    response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end

你知道这是什么原因吗?不,我从来没有。虽然我注意到Ryan Bates的网站上也存在同样的问题。我可能会尝试用rails pjax gem重写我的站点,看看这是否能让我的行为更加可靠。我会发布,如果我得到它的工作。我只是检查了你的网站,我没有注意到这个问题。这可能是您的机器/浏览器特有的问题吗?我认为这个问题只发生在IE 8I中。我似乎无法用上面的代码解决这个问题。。我应该把这段代码放在哪里呢?在应用程序控制器中设置过滤器之后,随着时间的推移,这个问题似乎已经自行解决了。我不知道为什么,但你的回答对我来说最有意义,那是某种缓存问题。我不知道在这两年中,主流浏览器是否改变了处理缓存的方式,或者我使用的ruby gem是否在此期间进行了更新,但无论哪种方式,问题似乎都得到了解决。我尝试在应用程序中添加
response.headers[“Cache Control”]
,然后再进行筛选,但即使当我从chrome的控制台看到标题时,它被设置为
must revalidate,private,max age=0
,从而从缓存中获取原始脚本。
if request.xhr?
    response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end