You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:13:12