Rails 7.2下Capybara调用visit加载example.com而非应用路由问题求助
Rails 7.2 中 Capybara + RSpec 在 Docker 容器内访问应用跳转到 www.example.com 的解决方案
问题重现
此前在 Rails 4/5/6 版本中,我一直用 Capybara 搭配 RSpec,在 Docker 容器里无需 Selenium 就能正常运行端到端测试。但升级到 Rails 7.2 后,相同测试直接失败——调用 visit '/posts' 时没有访问应用资源,反而加载了 www.example.com,触发 Rails 主机授权拦截,报错提示需要将该主机添加到配置白名单。
开发环境
- OSX Mac M1 ver. 14.5
- Docker version 27.1.1, build 6312585
- ruby 3.3.4 (aarch64-linux)
- Rails 7.2.0
- rspec-rails 6.1.4
- Capybara 3.40.0
测试代码及报错片段
测试文件 spec/features/post_spec.rb:
require 'rails_helper' describe 'Posts', type: :feature do it 'visitings' do visit '/posts' expect(page).to have_content 'New post' end end
执行测试命令:
docker exec -it app-container-name rspec
报错信息:
F. Failures: 1) Posts visitings Failure/Error: expect(page).to have_content 'New post' expected to find text "New post" in "Blocked hosts: www.example.com\nTo allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:\nconfig.hosts << \"www.example.com\"\nFor more details view: the Host Authorization guide" # ./spec/features/post_spec.rb:6:in `block (2 levels) in <top (required)>' Finished in 0.09256 seconds (files took 2.87 seconds to load) 2 examples, 1 failure Failed examples: rspec ./spec/features/post_spec.rb:4 # Posts visitings
问题原因
Rails 7.2 强化了主机授权的默认安全策略,仅允许信任的主机访问应用。而 Capybara 在使用 rack_test 驱动(无 Selenium 场景)时,默认请求的主机头被设为 www.example.com,该主机不在 Rails 测试环境的默认白名单内,因此被拦截。
解决方案
1. 调整测试环境的主机授权配置
在 config/environments/test.rb 中添加允许的主机,可选以下方案:
# 方案一:直接添加 www.example.com 到白名单 config.hosts << "www.example.com" # 方案二:测试环境下允许所有主机(灵活但仅建议测试用) config.hosts = nil # 方案三:根据容器主机名配置(更安全,推荐) config.hosts << ENV.fetch("APP_HOST", "localhost")
2. 配置 Capybara 指向正确的应用主机
在 spec/rails_helper.rb 或 spec/spec_helper.rb 中设置 Capybara 的主机参数:
# 指定应用访问地址 Capybara.app_host = "http://#{ENV.fetch('APP_HOST', 'localhost')}" # 设置服务器监听地址(适配 Docker 容器网络) Capybara.server_host = ENV.fetch('APP_HOST', '0.0.0.0')
3. 同步 Docker 容器主机名
启动 Docker 容器时指定主机名,确保和配置一致:
docker run --hostname app-container-name -e APP_HOST=app-container-name ...
4. 确认测试驱动配置
确保测试使用 rack_test 驱动(符合无 Selenium 的场景),在 spec/rails_helper.rb 中添加:
RSpec.configure do |config| config.before(:each, type: :feature) do driven_by :rack_test end end
调整以上配置后,Capybara 的请求会正确指向 Docker 容器内的 Rails 应用,不再跳转到 www.example.com。
内容的提问来源于stack exchange,提问作者Nellinux
相关产品推荐
相关产品推荐

