【发布时间】:2012-09-25 16:40:53
【问题描述】:
我们的团队最近遇到了一个最初的边缘情况问题,当用户从具有某种 javascript 呈现(无论是 Ajax、选项卡等)的页面单击浏览器的后退按钮时,会显示原始 javascript。要重新创建,我们遵循以下步骤:
- 访问用户职位申请索引
- 点击一个按钮进入管理职位发布页面
- 点击一个标签(使用 bettertabs gem)
- 点击浏览器的返回按钮
前面的步骤会显示:
(function() {
$(".job_applications").html("<li class=\"job_posting_application\">\n
...
...
...
...
);
}).call(this);
在某些偶然发生的情况下,您无需在返回上一页之前单击选项卡,但它仍会呈现原始 javascript。归根结底,似乎最后渲染的模板正在被缓存,这在浏览器方面是正常的和预期的,但会导致我认为是一个更大的问题。
Layouts and Rendering 部分中的 Rails 指南状态,特别是关于模板的 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
(您可以参考上面显示的整个请求in this pastie)
考虑到我们没有为这个请求提供任何 JSON,并且没有为这个路由的默认格式 :json 提供路由规范,我无法理解为什么它会被处理为 JSON。
此外,在此操作中调试request.format 的值时,它会返回application/json。
另一个场景是在另一个控制器 (users/company_admin_metrics#index) 中,它只包含一个 index.html.slim 模板。导航到此页面时,服务器日志显示它在layouts/users 内呈现users/company_admin_metrics/index.html.slim。当我创建一个空白的 js.coffee 模板时:
$ touch app/views/users/company_admin_metrics/index.js.coffee
并直接导航到该索引页面,服务器日志显示它呈现了users/company_admin_metrics/index.js.coffee,这进一步暴露了某个潜在的关于模板呈现优先级的问题。
有没有人遇到过类似的问题可以解决这个问题?
我们的堆栈
下面是这个特定问题的基本参与者的分钟列表:
- Rails 3.2.6
- Coffee-Rails 3.2.1
- Bettertabs 1.2.6
此请求取决于通过解析 JSON 并返回 Ruby 对象的客户端 gem 对我们的职位发布 API 的请求,但这些请求与此特定应用程序的耦合方式不会冲突并导致 this em> 应用程序的内容类型为application/json,用于上述此类请求。
【问题讨论】:
-
非常深入,但读完所有这些我的眼睛都呆滞了。您需要重新定义问题,但要简明扼要地说明您的问题。忘记与问题没有直接关系的任何事情。
-
在陈述你的问题时,请准确描述你做了什么,你预期会发生什么,以及实际发生了什么。这包括准确显示 AJAX 请求的外观以及“直接导航”的外观。您可能需要在 AJAX 调用中更明确地说明请求的 mimetype。
标签: jquery ruby-on-rails ajax