How Spring Boot Handles Cross-Origin Requests

This article explains the fundamentals of CORS, why browsers enforce the same‑origin policy, how Spring Boot detects and processes cross‑origin and preflight requests, and provides a minimal configuration and JavaScript example to resolve CORS issues in a Spring Boot application.

Shepherd Advanced Notes
Shepherd Advanced Notes
Shepherd Advanced Notes
How Spring Boot Handles Cross-Origin Requests

Overview

Cross‑origin requests are common in modern web development and can affect security, user experience, and business requirements. The article outlines why the browser’s Same‑Origin Policy exists and how improper CORS handling can block functionality.

What Is Cross‑Origin?

The Same‑Origin Policy treats two URLs as same origin only when protocol, host, and port are identical. If any of these three parts differ, the request is considered cross‑origin.

Why the Policy Exists

Browsers modify the Origin header to the current site’s domain. When a page tries to access a resource with a different scheme, host, or port, the browser blocks the request to protect users from malicious sites.

Typical Cross‑Origin Scenarios

http://www.bilibili.com
https://www.bilibili.com:8086
http://admin.www.bilibili.com

These examples illustrate differences in scheme, port, and host that trigger the policy.

How Spring Boot Determines a Cross‑Origin Request

Spring Boot’s CorsUtils.isCorsRequest(HttpServletRequest request) extracts the Origin header, parses its scheme, host, and port, and compares them with the request’s own values. If any component differs, the method returns true, indicating a cross‑origin request.

package org.springframework.web.cors;
public abstract class CorsUtils {
    public static boolean isCorsRequest(HttpServletRequest request) {
        String origin = request.getHeader("Origin");
        if (origin == null) {
            return false;
        } else {
            UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build();
            String scheme = request.getScheme();
            String host = request.getServerName();
            int port = request.getServerPort();
            return !ObjectUtils.nullSafeEquals(scheme, originUrl.getScheme())
                || !ObjectUtils.nullSafeEquals(host, originUrl.getHost())
                || getPort(scheme, port) != getPort(originUrl.getScheme(), originUrl.getPort());
        }
    }
}

Preflight Requests

A preflight request (HTTP OPTIONS) is sent before a complex cross‑origin request to verify that the server permits the actual request. It is triggered when the request uses a non‑simple method (e.g., PUT, DELETE), includes custom headers, or has a non‑simple Content‑Type.

When a Preflight Is Sent

Method is not GET or POST (e.g., PUT, DELETE).

Custom header such as X-Custom-Header is present. Content‑Type is not one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.

Server‑Side CORS Configuration

The server must enable CORS and explicitly allow the requesting origin; otherwise the preflight fails.

Detecting a Preflight Request in Spring Boot

public static boolean isPreFlightRequest(HttpServletRequest request) {
    // OPTIONS method + Origin header + Access‑Control‑Request‑Method header
    return HttpMethod.OPTIONS.matches(request.getMethod())
        && request.getHeader("Origin") != null
        && request.getHeader("Access-Control-Request-Method") != null;
}

How Spring Boot Decides to Allow a Request

The framework checks the allowedOrigins list. If the list is empty, contains "*", or includes the request’s origin, the request is permitted; otherwise it is rejected. private List<String> allowedOrigins; When ObjectUtils.isEmpty(this.allowedOrigins) or this.allowedOrigins.contains("*") is false and the origin is not in the list, the request is blocked.

Minimal CORS Configuration for Spring Boot

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        // config.setAllowCredentials(true); // avoid using with wildcard origin
        config.addAllowedOrigin("*"); // allow any domain
        config.addAllowedHeader("*"); // allow any header
        config.addAllowedMethod("*"); // allow any HTTP method
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

Note: config.addAllowedOrigin("*") must not be used together with setAllowCredentials(true), otherwise Spring Boot throws an error.

Testing CORS with JavaScript

var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:8081/admin/captcha/v1/generateCaptcha');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('authracation', 'abcdefghijklmnopqrstuvwxyz');
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
};
xhr.send('{}');

Run the script in the browser console (F12). It works in both IE and Chrome after adjusting the request URL to match your environment.

Cross‑origin illustration
Cross‑origin illustration
Spring Boot CORS source code
Spring Boot CORS source code
Browser CORS error screenshot
Browser CORS error screenshot
Preflight request handling
Preflight request handling
Allowed origins logic
Allowed origins logic
CorsFilter bean configuration
CorsFilter bean configuration
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaConfigurationSpring BootCORSCross-OriginPreflight
Shepherd Advanced Notes
Written by

Shepherd Advanced Notes

Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.