从 Rails 设置 document.domain 的 DRY 方式

Posted

技术标签:

【中文标题】从 Rails 设置 document.domain 的 DRY 方式【英文标题】:DRY way for setting document.domain from Rails 【发布时间】:2016-06-12 20:52:33 【问题描述】:

我有一个 Rails 应用程序,它使用了两个想要在 javascript 中进行通信的子域。有效设置document.domain = mydomain.com 的最干燥方式是什么?

使其不那么直截了当的条件

    这在域为localhost 的开发或测试环境中应该不是问题。 这也需要在某些不加载主 JavaScript 文件的页面上设置

条件1 让我认为我要么想依赖一个从location.host 解析根域的正则表达式,要么在erb 中进行切换。

条件2 让我觉得最好编写一次并将其放入资产管道并在必要时包含它。

最佳潜在解决方案

创建一个类似domain_setter.js.erb 的文件(内容如下),将其添加到预编译列表中,并将其包含在所有必要的位置(\\= require domain_setter 在清单中或javascript_include_tag 'domain_setter' 用于没有清单的页面)。

<%- if Rails.env.production? %>
  document.domain = 'mydomain.com';
<%- end %>

更新当前解决方案

此解决方案更具动态性,不需要对域进行硬编码。仍然不是最好的,但它正在工作...... 大部分 :-/

(function() 
  var domain = /^(?:https?\:\/\/)?.*?([^.]+\.[^.]+?)(?:\:\d+)?$/.exec(location.host);

  if (domain == null) 
    document.domain = 'localhost';
   else 
    document.domain = domain[1];
  
)();

tl;博士

使用 Rails 设置多页 document.domain 的 DRY 方法是什么?

【问题讨论】:

添加一些背景知识是为了允许同一域的不同子域上的两个页面能够通过 JavaScript 进行通信。即我希望foo.mydomain.combar.mydomain.com 进行通信,这需要他们都拥有较低的域集mydomain.com 【参考方案1】:

我认为您正在寻找跨域资源共享 (CORS)。这允许 javascript 跨不同域发出 AJAX $.get/post 请求。

这是一个帮助您入门的 Rails 库:https://github.com/cyu/rack-cors#rails

您需要将origins 属性设置为yoursubdomain.herokuapp.com

【讨论】:

这与 CORS 密切相关,但我不是通过 Ajax 在两个不同的域之间进行通信,而是在不同的子域上寻找两个页面来通过 JavaScript 进行通信。举个小例子,在任何页面上打开一个控制台并输入window.open('/')。在刚刚打开的窗口中,在控制台中输入window.opener.console.log('back to you original page'),您将在原始窗口的控制台中看到该输出。这不可能跨子域,除非它们的域设置得较低。 啊,你看过postmessage API了吗? developer.mozilla.org/en-US/docs/Web/API/Window/postMessage 我刚看了一下,它非常有用,特别是对于与其他域的通信。我觉得当两个窗口都有相同的document.domain时直接调用参数会稍微安全和方便。

以上是关于从 Rails 设置 document.domain 的 DRY 方式的主要内容,如果未能解决你的问题,请参考以下文章

从 Rails 5 开始,何时需要手动设置 :inverse_of?

从 YML 文件设置 rails 重定向

在 Hostmonster 上设置 Rails

从rails中的yaml获取变量

Rails - AdminMailer - 设置发件人姓名

sh 设置OSX机器从零到很棒。使用Homebrew(和桶,字体等)。专注于Ruby / Rails开发,包括rvm,xquartz,