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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:43:19