在跨域请求中,浏览器对非简单请求(如携带自定义头 Authorization
)会先发送 OPTIONS
预检请求(Preflight)。后端需要正确处理预检请求并返回正确的响应头,以允许后续的实际请求。以下是解决方案:
1. 后端需配置的响应头
在响应 OPTIONS
预检请求时,后端需返回以下关键头:
Access-Control-Allow-Origin
: 允许的源(如*
或具体域名)。Access-Control-Allow-Methods
: 允许的 HTTP 方法(如GET, POST, PUT, DELETE, OPTIONS
)。Access-Control-Allow-Headers
: 允许的自定义头(如Authorization, Content-Type
)。Access-Control-Max-Age
(可选): 预检结果的缓存时间(秒)。
2. 代码示例
(1)Node.js (Express)
app.use((req, res, next) => {
// 允许的源(需根据实际环境配置)
res.setHeader('Access-Control-Allow-Origin', 'https://your-frontend.com');
// 允许的自定义头
res.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type');
// 允许的方法
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
// 如果是 OPTIONS 预检请求,直接返回成功状态
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next(); // 继续处理其他请求
});
(2)Nginx 配置
location / {
# 允许的源和方法
add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# 关键:显式允许 Authorization 头
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
# OPTIONS 预检请求直接返回204
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; //缓存20天
return 204;
}
}
(3)Spring Boot (Java)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://your-frontend.com")
.allowedMethods("GET", "POST", "OPTIONS")
.allowedHeaders("Authorization", "Content-Type")
.maxAge(3600); //预检缓存时间
}
}
3.注意事项
避免使用通配符
*
Access-Control-Allow-Origin: *
不允许与Authorization
、自定义头或 Cookie(Credentials)同时使用。- 若需携带凭据(如 Cookie),必须指定具体域名,并设置:
Access-Control-Allow-Credentials: true
确保服务器正确处理 OPTIONS
OPTIONS
请求不应触发业务逻辑,直接返回正确响应头即可。
调试工具
- Chrome DevTools → Network →查看
OPTIONS
和实际请求的头信息。
- Chrome DevTools → Network →查看
通过以上配置,浏览器会在收到预检响应后,继续发送携带 Authorization
的实际请求。
内容由零声教学AI助手提供,问题来源于学员提问