Rails子域名JS资源跨域加载问题(Render URL重写场景)
你的核心问题是:example.com/library通过URL重写代理到library.example.com后,JS资源因CORS规则限制无法加载,已配置Rails的Rack::Cors但未生效。从请求/响应头能看出,请求的Origin为https://www.example.com,但响应头中缺少Access-Control-Allow-Origin相关字段,说明CORS配置未实际生效。
1. 优先清除Cloudflare缓存
响应头显示cf-cache-status: HIT,当前返回的是Cloudflare的缓存资源,而缓存的内容未包含CORS响应头。直接登录Cloudflare后台,找到library.example.com的缓存管理模块,执行清除全部缓存,之后重新测试请求。
2. 验证Rack::Cors中间件是否加载
登录library.example.com的服务器,运行以下命令确认中间件顺序:
rails middleware
检查输出是否有Rack::Cors排在最顶部(你配置了insert_before 0)。如果未出现该中间件:
- 确认
rack-corsgem已添加到Gemfile,并执行过bundle install - 检查
config/application.rb中的配置是否存在语法错误(比如引号、逗号格式)
3. 重启生产环境Rails应用
修改config/application.rb后,生产环境必须重启Rails服务器才能让新的中间件配置生效。如果使用Cloud66托管,触发应用重新部署或重启操作。
4. 针对静态资产的额外CORS配置
Rails预编译的资产(/assets/目录下的文件)可能被Web服务器(如Nginx)或Cloudflare直接提供,绕过了Rack中间件,导致Rack::Cors配置失效。此时需要在CDN或Web服务器层面配置CORS:
Cloudflare配置方式
进入Cloudflare的规则→CORS规则,添加规则:
- 匹配条件:
Host等于library.example.com,且URI Path包含/assets/ - 配置
Access-Control-Allow-Origin为https://example.com,https://www.example.com - 勾选
Access-Control-Allow-Methods,包含GET、OPTIONS等方法
Nginx配置方式
如果使用Nginx托管,在站点配置中添加:
location ~ ^/assets/ { add_header Access-Control-Allow-Origin "https://example.com https://www.example.com"; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; }
5. 可选:替换importmap的绝对URL为相对路径
利用Render的URL重写规则,将importmap中的绝对URL改为相对路径,让请求直接发送到example.com/assets/...,通过重写转发到library.example.com,从根源避免跨域:
<script type="importmap" data-turbo-track="reload">{ "imports": { "application": "/assets/application-ec9fb8976583666f9882e99ffe94f0391fc9ac4f1a32034d128201c87ac33ca3.js", "@hotwired/turbo-rails": "/assets/turbo.min-dfd93b3092d1d0ff56557294538d069bdbb28977d3987cb39bc0dd892f32fc57.js", "posthog-js": "/assets/posthog-js-27c6009e7053c1cc4ca4881a8510159e64330186618212ecf07859f877b74651.js", "posthog-custom": "/assets/src/posthog-e818ed81c53c6838d2ee7e8efc4f6faaf02a31bc3ea7e95fe0b56eacbdd4c025.js", "video-custom": "/assets/src/video-eefb06ba48956b0b5d08542119b3782b256b09daf694e20c8de3164ca020c541.js" } }</script>
内容的提问来源于stack exchange,提问作者sparkle

