Docker容器内Firefox运行Rails系统测试无法加载ActiveStorage Blob图片
问题根因
这是容器化远程Selenium测试场景下的典型配置问题:Capybara启动的随机端口测试服务器、Rails URL生成规则、浏览器子资源加载策略三者不匹配。
你手动在浏览器地址栏访问图片地址能下载,是因为导航请求的安全限制远低于img标签发起的子资源请求,不代表资源加载链路完全正常。之前的配置存在三个核心问题:
default_url_options只配置了主机名,没有同步Capybara实际运行的测试服务器端口,导致ActiveStorage生成重定向响应时,偶尔返回错误的端口或Host头- 测试环境没有放开Host校验、CSP图片源规则,随机端口的图片请求被浏览器安全策略拦截
- ActiveStorage默认的redirect模式在远程测试场景下,容易出现重定向目标地址和实际请求地址不匹配的问题
修复步骤
1. 修正Capybara配置
修改spec/rails_helper.rb中的Capybara全局及测试前置配置:
# 绑定所有网卡,允许Docker内网其他容器访问测试服务 Capybara.server_host = '0.0.0.0' # 自动为所有生成的URL拼接Capybara当前启动的测试服务端口 Capybara.always_include_port = true # 配置测试访问的根地址为web容器的Docker内网主机名 Capybara.app_host = "http://web" Capybara.default_host = "http://web" config.before(:each, type: :system) do driven_by :selenium, using: :firefox, screen_size: [1000, 1000], options: { browser: :remote, url: 'http://firefox:4444' } # 同步Rails URL生成的主机和端口配置,和Capybara实际运行端口一致 default_url_options[:host] = "web" default_url_options[:port] = Capybara.current_session.server.port end
2. 调整测试环境Rails配置
修改config/environments/test.rb,添加以下配置:
# 清空Host白名单校验,避免随机端口请求被Rails拦截 config.hosts.clear # 关闭CSRF源校验,避免重定向请求被拦截 config.action_controller.forgery_protection_origin_check = false # 配置CSP允许web容器任意端口加载图片资源,未开启CSP可跳过该段 config.content_security_policy do |policy| current_port = Capybara.current_session&.server&.port policy.img_src :self, "http://web:#{current_port || '*'}" end # 改用proxy模式处理ActiveStorage资源,避免重定向时Host/端口丢失 config.active_storage.resolve_model_to_route = :rails_storage_proxy
3. 确认Docker网络配置
你当前的docker-compose.yml不需要额外修改:Compose默认创建的桥接网络内,同网络下的容器可以互相访问任意端口,不需要把Capybara的随机端口映射到宿主机,firefox和web服务已经在同一网络下,满足访问要求。
验证
配置修改后重新执行测试,通过http://localhost:7900查看运行过程,图片请求会返回正确的image/* Content-Type,不再触发子资源拦截规则,SVG图片可以正常渲染。
内容的提问来源于stack exchange,提问作者preferred_anon
相关产品推荐
相关产品推荐

