WEB Cross-Origin/CORS Verification Process and Configuration Examples

Table of Contents


Cross-Origin Exceptions

Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If you encounter the above exception, you can use the following tool for online testing:


Browser Cross-Origin Resource Sharing (CORS) Verification Process

The browser's Cross-Origin Resource Sharing (CORS) verification process is mainly divided into two situations: simple requests and preflight requests:

1. Simple Request

Requests that meet the following conditions are considered simple requests:

  • Request methods: GET, POST, or HEAD
  • Request headers only include: Accept, Accept-Language, Content-Language, Content-Type
  • Content-Type values are limited to:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

Verification process:

  1. The browser sends the request directly, adding the Origin field in the request header
  2. The server returns a response, which needs to include the following response headers:
    • Access-Control-Allow-Origin
    • Access-Control-Allow-Credentials (optional)
    • Access-Control-Expose-Headers (optional)

2. Preflight Request

Requests that do not meet the simple request conditions require preflight, such as:

  • Using PUT, DELETE, and other methods
  • Sending JSON format data
  • Custom request headers

Verification process:

  1. The browser first sends an OPTIONS request for preflight
    • Includes Origin field
    • Access-Control-Request-Method field
    • Access-Control-Request-Headers field (if there are custom headers)
  2. The server responds to the preflight request, returning:
    • Access-Control-Allow-Origin
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Max-Age (optional, caching time for preflight results)
    • Access-Control-Allow-Credentials (optional)
  3. After the preflight passes, the browser sends the actual request
    • The actual request follows the same verification process as a simple request
    • The server returns the actual response data

3. Common Response Headers Explanation

  • Access-Control-Allow-Origin: Allowed domain names, such as * or specific domain names
  • Access-Control-Allow-Methods: Allowed request methods, such as GET, POST, PUT, DELETE
  • Access-Control-Allow-Headers: Allowed request headers
  • Access-Control-Allow-Credentials: Whether to allow sending cookies
  • Access-Control-Max-Age: Validity period of preflight requests
  • Access-Control-Expose-Headers: Response headers that the browser is allowed to access

4. Important Notes

  1. If you need to send cookies, you need to:
    • Set withCredentials = true on the frontend
    • Set Access-Control-Allow-Credentials = true on the server
    • Access-Control-Allow-Origin cannot be set to *, it must specify a specific domain name
  2. Caching of preflight requests:
    • Set caching time through Access-Control-Max-Age
    • The same request will not send a preflight request again during the cache period
  3. Security considerations:
    • Not recommended to use the * wildcard
    • Recommended to explicitly configure allowed domain names, methods, and request headers
    • Perform identity verification for sensitive operations

1. NGINX Configuration


server {
      listen 80; # 监听的端⼝
      server_name localhost; # 域名或ip
      location / { # 访问路径配置
        #允许跨域请求的域,* 代表所有
        add_header 'Access-Control-Allow-Origin' *;
        #允许带上cookie请求
        add_header 'Access-Control-Allow-Credentials' 'true';
        #允许请求的方法,比如 GET/POST/PUT/DELETE
        add_header 'Access-Control-Allow-Methods' *;
        #允许请求的header
        add_header 'Access-Control-Allow-Headers' *;

        if ($request_method = 'OPTIONS') {
          return204;
        }
        root /usr/share/nginx/html;# 根⽬录
        index index.html index.htm; # 默认⾸⻚
      }
      error_page 500 502 503 504 /50x.html; # 错误⻚⾯
      location = /50x.html {
        root html;
      }
}

2. JAVA Configuration

2.1. Spring Boot Annotation Method

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
public class TestController {
    // Add @CrossOrigin annotation to the controller class
    // origins = "*" means allowing access from all domain names
    // maxAge = 3600 means the validity period of the preflight request is 3600 seconds
}

2.2. Global Configuration


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")    // Path allowed for cross-origin access
                .allowedOrigins("*")    // Source allowed for cross-origin access
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")    // Allowed request methods
                .maxAge(3600)    // Preflight request cache time
                .allowedHeaders("*")    // Allowed headers
                .allowCredentials(true);    // Whether to send cookies
    }
}

2.3、Spring Security Configuration


import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
          // Other security configurations
            .csrf().disable();
    }
    
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

3、PHP Configuration

# Add at the entry file
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: *");

4、NODEJS Configuration

4.1、nodejs express Configuration


// ... existing code ...
// 1. Import modules
const express = require('express')
 
// 2. Create server
let app = express()
// Import cors (needs to be installed: this sets response header res.setHeader("Access-Control-Allow-Origin", "*"))
var cors = require('cors')
app.use(cors())

4.2、nodejs koa2 Configuration

const cors = require('koa2-cors');
const Koa = require('koa');

const app = new Koa();

app.use(cors({
  exposeHeaders: ['Authenticate'],
  credentials: true,
  allowMethods: ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'],
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));

curl Test Command

curl -i -X OPTIONS 'https://****************' \
-voa /dev/null \
-H 'Origin: http://********* (cross-origin address)' \
-H "Access-Control-Request-Method: GET (method)"

WEB Cross-Origin/CORS Configuration Examples

WEB Cross-Origin/CORS Configuration Examples HTTP cross-origin solutions|Cross-origin online debugging|CORS online debugging|JAVA|PHP|nodejs|nginx|Access-Control-Allow-Origin|Access-Control-Allow-Headers|Access-Control-Allow-Methods