Ste*_*ton 11 ajax jquery ruby-on-rails
我们的团队最近提出了一个最初的边缘案例问题,当用户从具有某种javascript呈现的页面(无论是Ajax,标签等)中单击浏览器的后退按钮时,将显示原始javascript.要重新创建,我们按照以下步骤操作:
之前的步骤将显示:
(function() {
$(".job_applications").html("<li class=\"job_posting_application\">\n
...
...
...
...
);
}).call(this);
Run Code Online (Sandbox Code Playgroud)
在一些命中或未命中的情况下,您不需要在返回上一页之前单击选项卡,但它仍然会呈现原始javascript.在一天结束时,似乎最后渲染的模板正在被缓存,这在浏览器的部分是正常的和预期的,但导致我认为是一个更大的问题.
Rails指南在" 布局和渲染 "部分中说明,特别是关于模板的MIME类型:
默认情况下,Rails将使用MIME内容类型text/html(或者如果使用:json选项则使用application/json,或者使用:xml选项的application/xml)来提供渲染操作的结果.
基于Rails默认值,我们的控制器的索引操作应该呈现我们的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
Run Code Online (Sandbox Code Playgroud)
但是,在此设置下,index.html.slim 应基于Rails默认值进行渲染.添加respond_to块时,缓存似乎仍然有效,控制器可能不关心respond_to块的存在:
def index
...
...
respond_to do |format|
format.html
format.js
end
end
Run Code Online (Sandbox Code Playgroud)
即使明确地,虽然有点臭,告诉每种格式呈现不同的模板,但似乎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
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,直接导航到浏览器中的页面(换句话说,不进行远程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
Run Code Online (Sandbox Code Playgroud)
(你可以参考上面这个贴图中显示的整个请求)
为什么它作为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
Run Code Online (Sandbox Code Playgroud)
并直接导航到该索引页面,服务器日志显示它呈现users/company_admin_metrics/index.js.coffee,这进一步暴露了有关模板呈现优先级的某个潜在问题.
有没有人遇到类似的问题可能会为此提供潜在的解决方案?
以下是这个特定问题的基本参与者的一小部分列表:
此请求取决于通过解析JSON并返回Ruby对象的客户端gem对我们的作业发布API的请求,但这些请求不会与此特定应用程序耦合,从而导致此应用程序具有内容类型application/json对于如上所述的这种请求.
小智 10
我认为你需要.js在ajax请求中将格式扩展名附加到URL.
可能发生的是用户正在使用html请求来执行index操作.然后ajax正在点击相同的URL /动作但请求javascript.当用户单击后退按钮时,浏览器无法区分两者之间的差异,因此使用最新的(javascript响应)./job_applicationsGET
最近开始在带有Rails 4.2.4的Chrome浏览器中看到此确切问题。似乎是一个众所周知且备受争议的问题。我们的团队通过将Vary标头添加到xhr请求中来解决该问题:
class ApplicationController < ActionController::Base
after_action :set_vary_header
private
# Fix a bug/issue/by-design(?) of browsers that have a hard time understanding
# what to do about our ajax search page. This header tells browsers to not cache
# the current contents of the page because previously when someone filtered results,
# went to the listing's external site, then hit Back, they'd only see the last
# ajax response snippet, not the full listings page for their search.
#
# Heated multi-year discussion on this issue in Chrome
# https://code.google.com/p/chromium/issues/detail?id=94369
#
# And continued by the Rails team:
# https://github.com/rails/jquery-ujs/issues/318
# https://github.com/rails/jquery-rails/issues/121
def set_vary_header
if request.xhr?
response.headers["Vary"] = "accept"
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2114 次 |
| 最近记录: |