Rails跨域报错:Origin与request.base_url不匹配求助
Rails跨域请求错误:Origin与request.base_url不匹配的解决方案
问题描述
前端部署在http://localhost:3006,调用Docker部署的Rails后端接口时,出现以下错误:
HTTP Origin header (http://localhost:3006) didn't match request.base_url (http://localhost:3000)
当前使用的docker-compose配置:
services: db: image: mysql environment: MYSQL_ALLOW_EMPTY_PASSWORD: true ports: - "3306:3306" frontend: image: moindev/moin-blog-frontend:$CI_COMMIT_SHORT_SHA ports: - "3006:3006" command: sh -c "npm install && npm run build && npm start" redis: image: redis command: redis-server ports: - "6379:6379" backend: image: moindev/moin-blog-backend:$CI_COMMIT_SHORT_SHA environment: BACKEND_URL: "http://backend:3000" BACKEND_HOST_NAME: "backend" ALLOWED_ORIGIN: "http://localhost:3006" google_client_secret: 'GOCSPX-tUcjQRmRs' google_client_id: "946502148013-u6hgpl13f8hum1cc" jwt_secret_key: 'a6b3c5f5232304609cc28f8e' ports: - "3000:3000" command: bundle exec rails s -b 0.0.0.0
已尝试的配置:
- application.rb中的CORS配置:
module Backend class Application < Rails::Application config.load_defaults 7.0 config.active_job.queue_adapter = :sidekiq config.default_url_options = { host: ENV['BACKEND_HOST_NAME'], port: 3000 } config.hosts << "ec2-35-1" # Configure CORS config.middleware.insert_before 0, Rack::Cors do allow do origins ENV['ALLOWED_ORIGIN'] resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head] end end end end
- config/initializers/cors.rb配置:
# config/initializers/cors.rb Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource( '*', headers: :any, expose: ["Authorization"], methods: [:get, :patch, :put, :delete, :post, :options, :show] ) end end
解决方案
1. 清理重复的CORS配置,避免冲突
同时在application.rb和cors.rb中配置Rack::Cors会导致中间件加载冲突,保留config/initializers/cors.rb并修改为:
# config/initializers/cors.rb Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins ENV['ALLOWED_ORIGIN'] || '*' # 优先使用环境变量,测试环境可 fallback 到* resource '*', headers: :any, expose: ["Authorization"], methods: [:get, :patch, :put, :delete, :post, :options, :head] end end
删除application.rb中的CORS配置块。
2. 修正Rails的base_url适配外部访问
Docker内部后端服务的request.base_url默认是容器内部地址http://backend:3000,但外部请求的Origin是http://localhost:3006,需让Rails识别外部访问地址:
- 修改
config/environments/production.rb(对应运行环境的配置文件):
config.action_controller.default_url_options = { host: 'localhost', port: 3000 } config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
- 更新docker-compose中后端的环境变量:
backend: environment: BACKEND_URL: "http://localhost:3000" # 改为外部可访问的地址 # 其他环境变量保持不变
3. 完善config.hosts配置
确保Rails允许外部主机和容器内部服务名访问:
# application.rb config.hosts << "localhost" # 外部访问的主机 config.hosts << "backend" # Docker容器内部服务名 # 若使用EC2部署,添加EC2的完整域名或IP
开发环境下可临时禁用主机检查(生产环境不建议):
config.hosts.clear
4. 确认前端请求地址
前端需调用外部可访问的后端地址http://localhost:3000,而非Docker内部的http://backend:3000(浏览器无法直接访问Docker内部服务名)。
验证步骤
执行以下命令重启所有服务,重新发起请求:
docker-compose down && docker-compose up --build
内容的提问来源于stack exchange,提问作者Moin Ahmed
相关产品推荐
相关产品推荐

