Javascript 如何处理调用浏览器不支持的代码的SJR响应';我还没有呢?
我想知道当用户通过AJAX与您的站点交互时,以及您同时部署站点的新版本时,如何缓解出现的问题 想象一个如下的场景: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中定义,并由用户的浏览器缓存。) 目前一切正常
用户通过单击“下一步”按钮浏览您的帖子。这个 “下一步”按钮通过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(); }
});