WEB Cross-Origin/CORS Verification Process and Configuration Examples
Table of Contents
- Cross-Origin Exceptions
- Browser Cross-Origin Resource Sharing (CORS) Verification Process
- 1. NGINX Configuration for CORS
- 2. JAVA Configuration for CORS
- 3. PHP Configuration for CORS
- 4. NODEJS Configuration for CORS
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:
- The browser sends the request directly, adding the Origin field in the request header
- 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:
- 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)
- 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)
- 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
- 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
- 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
- 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)"