🚦 Understanding CORS in Modern Web Development

December 5, 2025

A Complete Guide for Ruby on Rails, React, and React Native Developers

Cross-Origin Resource Sharing (CORS) is one of the most misunderstood parts of modern web development — and one of the most common sources of errors developers face when building APIs. If you’re working with Ruby on Rails, React, or React Native, you’ve likely encountered messages such as:

Article content
  • “CORS policy: No ‘Access-Control-Allow-Origin’ header present”
  • “Preflight response is not successful”
  • “Request blocked by CORS policy”

This article explains what CORS really is, how it works, and how to set it up correctly in a Rails API, especially when working with frontend apps like React and mobile apps built with React Native.

Advertise on RubyStackNews

RubyStackNews is a niche publication read by Ruby and Rails developers worldwide. Our audience includes senior engineers, tech leads, and decision-makers from the US, Europe, and Asia.

Sponsorship Options

📝 Article Sponsorship
Your brand featured inside a technical article (clearly marked as sponsored).
📌 Inline Sponsored Block
Highlighted sponsor section embedded within an article.
📎 Sidebar Sponsor
Logo + link displayed site-wide in the sidebar.
  • Highly targeted Ruby / Rails audience
  • Organic traffic from search and developer communities
  • No ad networks — direct sponsorships only

Interested in sponsoring RubyStackNews?

Contact via WhatsApp

🔍 What Is CORS?

CORS (Cross-Origin Resource Sharing) is a browser security mechanism. Its purpose is simple:

Prevent a website from making unauthorized requests to another website.

A cross-origin request occurs when the frontend and backend have different:

  • Domain
  • Subdomain
  • Port
  • Protocol (HTTP/HTTPS)

Example:


🧪 Preflight Requests (OPTIONS): Why They Matter

Before sending certain requests, browsers send a special OPTIONS preflight request.

A preflight is required when:

  • A request uses Authorization header
  • The method is not GET/POST (e.g., PUT, PATCH, DELETE)
  • The frontend sends custom headers
  • The content type is JSON

Rails must respond correctly with:

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Methods

If not, the browser blocks the request before it even hits your controller.


🛠 Setting up CORS in Ruby on Rails

Rails uses the rack-cors middleware. Add it if it’s not already present:

# Gemfile
gem 'rack-cors'

Then:

bundle install

Create or edit:

config/initializers/cors.rb

✔️ Recommended configuration for development

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3000', 'http://localhost:5173'

    resource '*',
      headers: :any,
      expose: ['Authorization'],
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

Important points:

  • origins must match EXACTLY the URL of your React app.
  • expose: [‘Authorization’] allows React to read your JWT or API tokens.
  • Preflight requests (OPTIONS) are handled automatically.

⚛️ CORS with React (Web)

React runs inside a browser → CORS will apply.

Typical axios configuration:

axios.get("https://api.example.com/users", {
  withCredentials: true,
});

If your API uses cookie authentication, you must add:

credentials: true

And this on the frontend:

axios.defaults.withCredentials = true;

📱 CORS with React Native

React Native is not a browser. It uses the phone’s networking stack.

Therefore:

✔️ It does not enforce CORS ❌ It does not send preflight automatically ✔️ It can call almost any API without CORS errors

This means:

fetch("https://api.example.com/users")

…works without any CORS configuration.

The only time React Native has CORS errors is when developers manually set the Origin header — which should never be done.


🔐 Using JWT, Devise, or Token Authentication?

If your Rails API returns tokens through headers:

expose: ['Authorization']

If you use cookies:

credentials: true

And in your controller:

response.set_header('Authorization', token)

🔥 Full Production Example

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'https://myfrontend.com', 'https://admin.myfrontend.com'

    resource '*',
      headers: :any,
      expose: ['Authorization'],
      methods: %i[get post put patch delete options head]
  end

  # Allow React Native and mobile apps with no origin header
  allow do
    origins '*'
    resource '*',
      headers: :any,
      methods: :any
  end
end

🧨 Common CORS Errors and How to Fix Them

1. “Blocked by CORS policy”

Usually means the frontend URL is missing from origins.

2. Preflight request returns 500

A controller or gem is capturing the OPTIONS request. Fix: Ensure rack-cors is inserted BEFORE other middlewares:

insert_before 0

3. “No Access-Control-Allow-Origin header”

Backend isn’t returning CORS headers.

4. Cookies not sent

Your config must contain:

credentials: true

And React must use:

withCredentials: true

Cookies + * origins is forbidden. You must use explicit origins.



📝 Final Thoughts

CORS is not an error — it is a browser safety mechanism. Once you understand origins, headers, and preflight, the configuration becomes predictable and easy to manage.

With a properly configured Rails API, your React app will communicate smoothly, and your React Native app will avoid unnecessary restrictions.

If you’re building a full-stack application in 2025, mastering CORS is essential.

Article content

Leave a comment