我们的团队最近遇到了一个最初的边缘案例问题,当用户从具有某种 javascript 呈现(例如 Ajax、选项卡等)的页面单击浏览器的后退按钮时,将显示原始 javascript。要重新创建,我们按照以下步骤操作:
- 访问用户工作申请索引
- 单击一个按钮到管理职位发布页面
- 单击一个选项卡(使用 bettertabs gem)
- 单击浏览器的返回按钮
前面的步骤将显示:
(function() {
$(".job_applications").html("<li class=\"job_posting_application\">\n
...
...
...
...
);
}).call(this);
在某些偶然发生的情况下,您无需在返回上一页之前单击选项卡,但它仍会呈现原始 javascript。归根结底,似乎最后渲染的模板正在被缓存,这在浏览器方面是正常的和预期的,但会导致我认为是一个更大的问题。
Rails 指南在Layouts and Rendering部分中指出,特别是关于模板的 MIME 类型:
默认情况下,Rails 将使用 text/html 的 MIME 内容类型(或 application/json 如果您使用 :json 选项,或 application/xml 用于 :xml 选项)提供渲染操作的结果。
基于 Rails 的默认设置,我们的控制器的 index 动作应该会渲染我们的index.html.slim
模板。但是,在跟踪服务器日志的同时对该页面进行非远程调用(例如,直接导航到浏览器中的页面)时,我们注意到它实际上呈现index.js.coffee
. 下面是我们的控制器操作,请注意我们没有明确响应 html 或 js 格式,因为我们可能应该考虑此页面中的覆盖功能:
def index
@company_id, @division_id, @job_posting_id = params[:company_id], params[:division_id], params[:job_posting_id]
# API requests are made here to instantiate @job_posting, et al.,
# but are not shown for brevity
authorize! :manage, @job_posting
@survey = @job_posting.survey
@job_applications = @job_posting.job_applications(sort_column, sort_direction)
end
但是,鉴于此设置,index.html.slim
应根据 Rails 默认值进行渲染。添加respond_to
块时,缓存似乎仍然有效,控制器可能不太关心respond_to
块的存在:
def index
...
...
respond_to do |format|
format.html
format.js
end
end
即使明确地,虽然很臭,告诉每种格式呈现不同的模板,模板似乎js.coffee
优先于html.slim
模板:
def index
...
...
respond_to do |format|
format.html { render template: "users/job_posting_applications/index" }
format.js { render template: "users/job_posting_applications/ajax" }
end
end
在上述情况下,直接导航到浏览器中的页面(换句话说,不进行远程 Ajax 调用),服务器日志将呈现ajax.js.coffee
,即使 Rails 默认为 html,除非另有说明。
说了这么多,这里有一些其他的发现:
Started GET "/users/companies/1/divisions/18/job_postings/349421/applications" for 127.0.0.1 at 2012-10-03 19:55:26 -0400
Processing by Users::JobPostingApplicationsController#index as JSON
(您可以在此粘贴中引用上面显示的整个请求)
考虑到我们没有在此请求上提供任何 JSON,并且在路由中没有针对:json
此路由的默认格式的路由规范,为什么它以 JSON 格式处理超出了我的理解。
此外,在调试request.format
此操作中的值时,它会返回application/json
.
另一个场景是在另一个users/company_admin_metrics#index
仅包含一个index.html.slim
模板的控制器 ( ) 中。导航到此页面时,服务器日志显示它users/company_admin_metrics/index.html.slim
在layouts/users
. 当我创建一个空白 js.coffee 模板时:
$ touch app/views/users/company_admin_metrics/index.js.coffee
并直接导航到该索引页面,服务器日志显示它已渲染users/company_admin_metrics/index.js.coffee
,这进一步暴露了某处有关模板渲染优先级的潜在问题。
有没有人遇到过类似的问题,可能会为此提供潜在的解决方案?
我们的堆栈
以下是这个特定问题的基本参与者的分钟列表:
- 导轨 3.2.6
- Coffee-Rails 3.2.1
- 更好的标签 1.2.6
此请求取决于通过解析 JSON 并返回 Ruby 对象的客户端 gem 对我们的职位发布 API 的请求,但这些请求与此特定应用程序的耦合方式不会发生冲突并导致此应用程序的内容类型为application/json
对于上述请求。