// +---------------------------------------------------------------------- // 分层跨域配置。本文件被 **两套** CORS 机制读取,改动前务必读完注释: // // A. ywxapp\middleware\CrossDomain(本项目自研,真正的执行者) // → 读 app_cross(按应用名分层白名单)+ allowed_methods/headers/max_age/credentials // B. think\cors\HandleCors(topthink/think-cors,经服务发现自动挂载,见 vendor/services.php) // → 读 paths / allowed_origins / allowed_methods / allowed_headers / exposed_headers ... // 注意:它的构造函数会对 allowed_methods / allowed_headers 执行 array_map, // 因此这两项**必须是数组**;写成 'GET, POST' 这样的字符串会在每个请求 // 构造函数里抛 TypeError(array_map(): Argument #2 must be of type array, string given)。 // // 现状:跨域已由 CrossDomain 分层接管,think-cors 保持「空转」(paths 为空 → 不匹配任何路径)。 // 若将来想让 think-cors 真正接管,把 paths 配上路径即可,但**必须先移除 CrossDomain**, // 否则两条链路会重复输出 CORS 头。 // // app_cross 按应用名取规则,取值: // '*' 全放开(无凭证模式,公开 API 可用) // 'a.com,b.com' 精确白名单(支持凭证) // '*.example' 通配子域 // '' 禁止跨域(默认;同源页面不受影响) // // 安全策略:backend / member / frontend 一律留空(零跨域), // 仅 api 对外开放;生产建议把 api 也收紧为精确白名单。 return [ 'app_cross' => [ 'api' => env('CORS_API_ORIGINS', '*'), 'backend' => env('CORS_BACKEND_ORIGINS', ''), 'member' => env('CORS_MEMBER_ORIGINS', ''), 'frontend' => env('CORS_FRONTEND_ORIGINS', ''), // 未列出的应用(含 addon 应用、index 兜底)默认禁跨域 'default' => env('CORS_ORIGINS', ''), ], // 预检/实际请求允许的方法(**数组**,think-cors 强制要求) 'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], // 允许的请求头(**数组**,含本框架 JWT 鉴权实际使用的 Authorization / Authorization-Refresh) 'allowed_headers' => [ 'Content-Type', 'Authorization', 'Authorization-Refresh', 'X-Requested-With', 'X-CSRF-TOKEN', 'token', 'X-Token', ], // 预检结果缓存(秒) 'max_age' => 86400, // 白名单模式下允许携带 Cookie 凭证(对 '*' 无效,浏览器强制忽略) 'supports_credentials' => true, // ==================== 以下为 think-cors 专用,保持空转 ==================== // 空数组 → HandleCors::hasMatchingPath() 恒 false → 直接放行,不再输出任何 CORS 头。 // 不要配成 'api/*' 之类,否则与 CrossDomain 重复输出。 'paths' => [], 'allowed_origins' => [], 'allowed_origins_patterns' => [], 'exposed_headers' => [], ];