Rails控制器在浏览器中呈现JSON

时间:2014-10-23 14:58:12

标签: ruby-on-rails json

我有一个简单的控制器,我已回复htmljson。我在Backbone应用程序中使用json响应。一切都按预期工作,除了当我单击使用show方法的链接,然后单击后退按钮时,index方法只会在浏览器中输出一大串JSON 。如果我刷新,它会按预期显示HTML。这是控制器。

class RecipesController < ApplicationController
  def index
    @user = User.find(params[:user_id])
    @recipes = Recipe.all

    respond_to do |format|
      format.html
      format.json { render json: Recipe.where(user_id: params[:user_id]).featured }
    end
  end
  ...
end

我尝试添加response.xhr?的检查,如果它是AJAX请求,则只渲染JSON,但这不起作用。

修改

这是一款不使用turbolinks的Rails 3应用程序。

编辑2

以下是相关的Backbone代码。

# app/assets/javascripts/collections/recipe_list_.js.cofee
@App.Collections.RecipeList = Backbone.Collection.extend
  url: ->
    "/users/#{@userId}/recipes"
  model: window.App.Models.Recipe
  initialize: (opts) ->
    @userId = opts.userId


# app/assets/javascripts/app.js.coffee
$ ->
  urlAry = window.location.href.split('/')
  userId = urlAry[urlAry.length - 2]
  App = window.App
  App.recipeList = new App.Collections.RecipeList(userId: userId)
  App.recipeListView = new App.Views.RecipeListView

4 个答案:

答案 0 :(得分:4)

如果您指的是chrome和turbolinks问题,那么一个简单的解决方法是禁用对ajax请求的缓存:

$.ajaxSetup({cache: false})

答案 1 :(得分:3)

我打赌它是由于turbolink或基于ajax的页面呈现(骨干,remote=true,...)

我总是禁用turbolink并控制哪些链接是remote=true,对于所有ajax响应我在最后插入这个javascript行

history.pushState(null, '', '/the/requested/url' );

如果您不想为每个链接响应手动实现此行,可以将其包装在ajax:complete事件(more info)中,并假设turbolink有一个事件你也可以使用。

诀窍的第二部分是绑定popstate,以便当您的用户点击&#34;返回&#34;按钮页面将从服务器刷新(通过之前 pushState -ed的url)和ajax / js / json /不再显示任何响应。

setTimeout( function () {
  $(window).bind('popstate', function () {
    window.location = location.href;
  });
}, 500);

如您所见,我将popstate事件绑定包装在setTimeout中,因为如果您不这样做,您可能会遇到一些无限刷新页面的浏览器。

答案 2 :(得分:2)

您可以尝试使用/recipes.html 和/recipes.json 和/recipes/1.html和/recipes/1.json

而不是依赖于主干和历史记录来始终发送正确的标题

答案 3 :(得分:2)

您使用的是Chrome吗?如果是这样,这是一个已知问题。当您点击后退按钮时,chromes从缓存中提供页面,因为返回的是json,它是在屏幕上转储的内容。这篇文章有一些建议的解决方法

https://code.google.com/p/chromium/issues/detail?id=108766