本文总结了在微信 OAuth H5 项目中遇到的 CORS 跨域问题及其多种解决方案。
问题背景
前端域名:
https://h5.onefind.club后端 API:
https://api.onefind.club/interface-server/api/queryWeixinOpenIDByCode.json错误信息:
Access to XMLHttpRequest at 'https://api.onefind.club/...'
from origin 'https://h5.onefind.club' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决方案
方案一:后端添加 CORS 响应头(最佳方案)
后端服务器在响应中添加 CORS 相关的 HTTP 响应头。
适用场景
有后端服务器的修改权限
生产环境推荐方案
需要精细化控制跨域策略
实现方式
Node.js (Express)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://h5.onefind.club');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
// 处理 OPTIONS 预检请求
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
Java (Spring Boot)
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("https://h5.onefind.club");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
Nginx (后端 API 服务器)
location /interface-server/ {
# 添加 CORS 响应头
add_header 'Access-Control-Allow-Origin' 'https://h5.onefind.club' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type' always;
# 处理 OPTIONS 预检请求
if ($request_method = 'OPTIONS') {
return 204;
}
# 正常代理到后端应用
proxy_pass http://backend;
}
优缺点
方案二:Nginx 反向代理(前端服务器)
在前端服务器的 Nginx 配置中添加反向代理,将 API 请求转发到后端,避免浏览器的同源策略限制。
适用场景
只有前端服务器 Nginx 的修改权限
无法修改后端 API 服务器
快速解决跨域问题
实现方式
Nginx 配置 (h5.onefind.club)
server {
listen 443 ssl;
server_name h5.onefind.club;
# API 反向代理 - 解决 CORS 问题
location /interface-server/ {
proxy_pass https://api.onefind.club/interface-server/;
proxy_set_header Host api.onefind.club;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 前端静态文件
location / {
root /var/www/sites/h5.onefind.club/index;
try_files $uri $uri/ /index.html;
}
}
前端配置修改
// 修改前
apiBaseUrl: "https://api.onefind.club/",
// 修改后 - 使用相对路径
apiBaseUrl: "/",
请求流程对比
修改前(有 CORS 问题)
浏览器 → https://h5.onefind.club
↓ (跨域请求)
https://api.onefind.club/interface-server/api/xxx.json
❌ 被浏览器 CORS 策略阻止
修改后(无 CORS 问题)
浏览器 → https://h5.onefind.club/interface-server/api/xxx.json
↓ (同域请求)
Nginx 反向代理
↓
https://api.onefind.club/interface-server/api/xxx.json
✅ 无跨域问题
优缺点
方案三:开发环境代理
仅用于开发环境,生产环境仍需其他方案。
适用场景
本地开发调试
临时解决方案
Vite 配置
// vite.config.ts
export default defineConfig({
server: {
proxy: {
'/interface-server': {
target: 'https://api.onefind.club',
changeOrigin: true,
secure: true,
}
}
}
})
Vue CLI 配置
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/interface-server': {
target: 'https://api.onefind.club',
changeOrigin: true,
pathRewrite: {
'^/interface-server': '/interface-server'
}
}
}
}
}
优缺点
方案四:使用 WebSocket
WebSocket 协议不受同源策略限制,可以将数据传输改为 WebSocket。
适用场景
需要实时通信
复杂的跨域场景
优缺点
各方案对比
CORS 详解
什么是 CORS
CORS (Cross-Origin Resource Sharing,跨源资源共享) 是一种基于 HTTP 头的机制,允许服务器标示除了它自己以外的其它源(域、协议或端口),浏览器应该允许从这些源加载资源。
同源策略
浏览器默认的同源策略限制:
CORS 请求类型
1. 简单请求 (Simple Request)
同时满足以下条件:
方法:GET、HEAD、POST
头部:Accept、Accept-Language、Content-Language、Content-Type(仅限
application/x-www-form-urlencoded、multipart/form-data、text/plain)
不会触发预检请求。
2. 预检请求 (Preflight Request)
不满足简单请求条件的,浏览器会先发送 OPTIONS 请求:
OPTIONS /interface-server/api/xxx.json HTTP/1.1
Host: api.onefind.club
Origin: https://h5.onefind.club
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
服务器需要响应:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://h5.onefind.club
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
调试 CORS 问题
1. 浏览器控制台
查看 Console 中的 CORS 错误信息:
Access to XMLHttpRequest has been blocked by CORS policy
2. Network 面板
查看 OPTIONS 预检请求的响应
检查响应头中是否包含
Access-Control-Allow-Origin
3. curl 测试
# 测试是否支持 CORS
curl -I -H "Origin: https://h5.onefind.club" \
https://api.onefind.club/interface-server/api/queryWeixinOpenIDByCode.json
最佳实践
生产环境:优先使用后端添加 CORS 响应头
无后端权限:使用 Nginx 反向代理
开发环境:使用 devServer 代理
避免:JSONP、
no-cors模式等不安全方案