2

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

想象一个像下面这样的场景:


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

SJR 呈现这个 Javascript:

// in create.js.erb renderNewPost(<%= @post.to_json %>);

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

此时一切正常。

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

// in create.js.erb logSomething("hi!"); renderNewPost(<%= @post.to_json %>);

并将该功能添加logSomething到您的application.js.

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

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


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

4

1 回答 1

2

选项1:

一个简单的选择是,让响应尽可能独立,这意味着在您的示例中,您不会在log_something其他地方定义该方法,但也在同一个响应中。

选项 2:

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

before_action do
  response.headers['X-SJR-Version'] = '1.0.0'
end

并添加一些 Javascript 客户端代码,您可以在其中执行 AJAX 请求以检查版本是否仍然匹配。粗略的实现可能是这样的(未经测试):

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(); }
});

这利用了 jquery 钩子ajaxSuccess来执行版本检查。如果您使用常规 jquery-ujs rails 调用,您可能需要查看此页面。

现代方法:

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

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

因此,您很可能找不到针对此问题的开箱即用解决方案,而必须采用上述方法。

于 2018-08-08T07:09:50.543 回答