Skip to content

CORS 跨域配置

说明

CORS(Cross-Origin Resource Sharing)跨域资源共享是前后端分离架构必须处理的问题。通过 TORNADO_CORS_ORIGINS 环境变量配置允许的跨域源。实现位于 src/common/middleware/cors.py,在 BaseHandler.set_default_headers() 中调用。

配置项

环境变量默认值说明
TORNADO_CORS_ORIGINS空(允许所有源)允许的跨域源(逗号分隔)

配置示例

bash
# .env

# 允许所有源(开发环境)
TORNADO_CORS_ORIGINS=

# 允许指定源(生产环境)
TORNADO_CORS_ORIGINS=https://admin.example.com,https://www.example.com

生产环境

生产环境务必配置 TORNADO_CORS_ORIGINS 为具体域名,避免允许所有源带来的安全风险。

实现原理

python
# src/common/middleware/cors.py
from config.app import TORNADO_CORS_ORIGINS

# 解析白名单(逗号分隔)
_ALLOWED_ORIGINS = {o.strip() for o in TORNADO_CORS_ORIGINS.split(",") if o.strip()}


def cros_required(self):
    """为响应设置跨域相关头。"""
    origin = self.request.headers.get("Origin", "")

    # 配置了白名单:仅对匹配来源反射来源并允许携带凭据
    if _ALLOWED_ORIGINS:
        if origin in _ALLOWED_ORIGINS:
            self.set_header("Access-Control-Allow-Origin", origin)
            self.set_header("Access-Control-Allow-Credentials", "true")
            self.set_header("Vary", "Origin")
    else:
        # 未配置白名单:允许所有来源(不携带凭据)
        self.set_header("Access-Control-Allow-Origin", "*")

    # 安全相关响应头
    self.set_header("X-XSS-Protection", "1; mode=block")
    self.set_header("Content-Security-Policy", "default-src 'self'")

    # 允许的请求头和方法
    self.set_header("Access-Control-Allow-Headers", "*")
    self.set_header("Access-Control-Expose-Headers", "*")
    self.set_header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
    self.set_header("Content-Type", "application/json; charset=UTF-8")

    # 预检请求最大缓存时间(秒)
    self.set_header("Access-Control-Max-Age", "3600")

调用位置

CORS 在 BaseHandler.set_default_headers() 中调用,每个请求自动设置:

python
# src/core/base_handler.py
class BaseHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        super().set_default_headers()
        cros_required(self)      # 设置 CORS 头
        apply_trace_id(self)     # 设置 TraceID

CORS 头说明

响应头说明
Access-Control-Allow-Origin允许的来源(* 或具体域名)
Access-Control-Allow-Credentials是否允许携带凭据(Cookie 等)
Access-Control-Allow-Methods允许的 HTTP 方法
Access-Control-Allow-Headers允许的请求头
Access-Control-Expose-Headers允许前端读取的响应头
Access-Control-Max-Age预检请求缓存时间(秒)
Vary缓存键(白名单模式下使用)

预检请求

浏览器对跨域复杂请求(如 PUT/DELETE 或携带自定义 Header)会先发送 OPTIONS 预检请求。BaseHandler.options() 直接返回 204:

python
# src/core/base_handler.py
class BaseHandler(tornado.web.RequestHandler):
    def options(self, *args, **kwargs):
        """处理 CORS 预检请求,直接返回 204 无内容响应。"""
        self.set_status(204)
        self.finish()

总结

CORS 跨域配置具备以下特点:

1. 环境变量配置:通过 TORNADO_CORS_ORIGINS 灵活配置允许的源
2. 开发/生产分离:开发环境允许所有源,生产环境指定域名
3. 安全默认:未配置时允许所有源但不携带凭据
4. 自动生效:在 BaseHandler.set_default_headers() 中调用,每个请求自动设置
5. 预检处理:OPTIONS 请求直接返回 204,不进入业务逻辑

小蚂蚁云团队 · 提供技术支持