Javascript 如何处理调用浏览器不支持的代码的SJR响应';我还没有呢?

Javascript 如何处理调用浏览器不支持的代码的SJR响应';我还没有呢?,javascript,ruby-on-rails,ajax,Javascript,Ruby On Rails,Ajax,我想知道当用户通过AJAX与您的站点交互时,以及您同时部署站点的新版本时,如何缓解出现的问题 想象一个如下的场景: 用户通过单击“下一步”按钮浏览您的帖子。这个 “下一步”按钮通过XHR向服务器提交表单,然后服务器用服务器生成的Javascript响应(SJR)进行响应 SJR呈现以下Javascript: //在create.js.erb中 renderNewPost() (renderNewPost在连接的、缩小的application.js中定义,并由用户的浏览器缓存。) 目前一切正常

我想知道当用户通过AJAX与您的站点交互时,以及您同时部署站点的新版本时,如何缓解出现的问题

想象一个如下的场景:


用户通过单击“下一步”按钮浏览您的帖子。这个 “下一步”按钮通过XHR向服务器提交表单,然后服务器用服务器生成的Javascript响应(SJR)进行响应

SJR呈现以下Javascript:

//在create.js.erb中
renderNewPost()

renderNewPost
在连接的、缩小的
application.js
中定义,并由用户的浏览器缓存。)

目前一切正常

现在,作为一项新功能的一部分,您将端点的SJR更改为首先记录以下内容:

//在create.js.erb中
logSomething(“嗨!”);
renderNewPost()

并将函数
logSomething
添加到
application.js

用户再次单击“下一步”按钮。这一次,SJR用
logSomething('hi')
行响应。。。但是浏览器没有在任何地方定义
logSomething
,因为浏览器加载的
application.js
是第一个版本

现在,在刷新页面之前,用户将无法使用您的站点



我们如何解决这个问题?手头的问题有名称吗?

选项1:

一个简单的选择是,让响应尽可能独立,这意味着在您的示例中,您不会在其他地方定义
log\u something
方法,而是在相同的响应中定义

选项2:

另一个可能更通用的解决方案是,在应用程序控制器中的自定义响应头(比如
X-SJR-version
)中发送某种版本

before_action do
  response.headers['X-SJR-Version'] = '1.0.0'
end
并添加一些Javascript客户端代码,在其中执行AJAX请求,检查版本是否仍然匹配。 粗略的实现可能是这样的(未经测试):

这将使用jquery钩子来执行版本检查。如果您使用的是常规的jquery-ujs-rails调用,您可能需要检查页面

现代方法:

然而,现代rails应用程序通常不再使用服务器生成的javascript,因为那里的架构通常是自己编写客户端javascript(通常使用react、angular或vue),并使用JSON API端点从服务器获取数据,而javascript代码已经出现在页面的响应中,不需要加载其他JS

这样做的好处是,您可以使用API版本控制,而加载的javascript将保持旧版本,因此您可以顺利地切换到较新的API版本(通常您甚至不需要新的API版本,因为只有javascript会更改)


因此,您很可能无法找到解决此问题的现成解决方案,而必须采用类似于上述的方法

那么,您正在用户请求之间部署新版本?@gasc Yes。不知道为什么这被否决了:(
var version = null;
$(document).bind("ajaxSuccess", function(xhr, status){
   var newVersion = xhr.getResponseHeader('X-SJR-Version')
   if(version === null) { version = newVersion } // initial version
   if(newVersion !== version) { location.reload(); }
});