完整配置指南:过滤器、预检请求与多环境策略)
后端Web框架【免费下载链接】CodeIgniter4Open Source PHP Framework (originally from EllisLab)项目地址https://gitcode.com/gh_mirrors/co/CodeIgniter4点击查看免费下载CORSCross-Origin Resource Sharing跨域资源共享是基于 HTTP 头的安全机制它允许服务器声明除自身之外的哪些源域名、协议或端口可以被浏览器授权加载资源。CodeIgniter 4 自 4.5.0 起内置了 CORS 过滤器与辅助类cors过滤器 CodeIgniter\HTTP\Cors类本文将以官方文档 cors.rst 为骨架结合仓库源码与测试完整讲解配置项、路由/过滤器两种启用方式、预检Preflight请求处理、多配置切换以及底层实现原理。读完本文你将能为 API 或前后端分离应用正确配置、验证并调试 CORS同时避免通配符与凭据共用、缓存Vary头缺失等常见坑点。CORS 与 CodeIgniter 4 的解决方案跨域资源共享机制通过在 HTTP 请求与响应中添加头部向浏览器表明目标资源是否允许跨源共享从而帮助防御跨站请求伪造CSRF与数据窃取等恶意攻击。如果你对 CORS 请求头、预检请求等基础概念尚不熟悉建议先阅读 MDN 关于 CORS 的文档可在 app/Config/Cors.php 头部注释中找到官方推荐链接。CodeIgniter 4 为开发者提供了两个层次的 CORS 支持4.5.0 版本新增见 v4.5.0 更新日志CORS 过滤器实现位于 system/Filters/Cors.php通过before/after生命周期自动注入响应头、终结预检请求CORS 辅助类实现位于 system/HTTP/Cors.php负责实际的头生成、源校验与配置工厂过滤器内部即委托该类工作。过滤器别名cors已在 system/Config/Filters.php 与 app/Config/Filters.php 的$aliases中预注册指向CodeIgniter\Filters\Cors开箱即用。配置 CORS$default配置项详解CORS 的默认配置统一放在app/Config/Cors.php的$default属性中。完整默认配置如下仓库实际文件 app/Config/Cors.php?php namespace Config; use CodeIgniter\Config\BaseConfig; class Cors extends BaseConfig { public array $default [ allowedOrigins [], allowedOriginsPatterns [], supportsCredentials false, allowedHeaders [], exposedHeaders [], allowedMethods [], maxAge 7200, ]; }必须设置的三个核心项文档明确指出$default中以下三项是开启 CORS 的最低要求配置项含义对应响应头allowedOrigins显式列出允许的 Origin如[http://localhost:8080]、[https://www.example.com]Access-Control-Allow-OriginallowedHeaders显式列出允许的 HTTP 请求头如[Authorization, Content-Type]Access-Control-Allow-HeadersallowedMethods显式列出允许的 HTTP 方法如[GET, POST, PUT, DELETE]Access-Control-Allow-Methods⚠️最小权限原则基于 least privilege 原则只应允许最低限度的 Origin、Methods 与 Headers切勿贪多。其余配置项allowedOriginsPatternsOrigin 正则模式列表。文档与源码注释说明每个模式会被包成#\Apattern\z#进行整串匹配例如[https://\w\.example\.com]可匹配https://api.example.com。匹配成功的源会动态回填到Access-Control-Allow-Origin并追加Vary: OriginsupportsCredentials若跨源请求携带凭据如 Cookie必须设为true此时会输出Access-Control-Allow-Credentials: trueexposedHeaders允许浏览器脚本读取的响应头列表Access-Control-Expose-Headers如[Content-Length, X-Kuma-Revision]maxAge预检请求结果可被浏览器缓存的最大秒数Access-Control-Max-Age默认72002 小时。源码中的合法性约束在 system/HTTP/Cors.php 中有两条硬性校验配置不合规会抛出ConfigException通配符只能单独使用checkWildcard()要求若配置中使用了*则该数组必须恰好为[*]元素个数为 1否则抛错凭据请求禁止通配符checkWildcardAndCredentials()规定当supportsCredentials为true时Access-Control-Allow-Origin与Access-Control-Allow-Headers的值不得是*通配符浏览器规范要求源码注释也明确提示不推荐使用通配符。启用 CORS过滤器 OPTIONS 路由缺一不可启用 CORS 需要同时完成两件事为允许 CORS 的路由指定cors过滤器为 CORS 预检请求添加OPTIONS路由。⚠️关键警告除了 Required Filters必需过滤器见 app/Config/Filters.php 的$required列表之外控制器过滤器在路由不存在时不会执行。因此不添加 OPTIONS 路由预检请求将直接 404CORS 功能失效。而 CORS 过滤器会接管所有预检请求所以 OPTIONS 路由的闭包控制器通常不会被真正调用。方式一在 Routes.php 中按路由组设置在app/Config/Routes.php中为路由组绑定cors过滤器示例源自 cors/001.phpuse CodeIgniter\Router\RouteCollection; $routes-group(, [filter cors], static function (RouteCollection $routes): void { $routes-resource(product); // 为预检请求添加 OPTIONS 路由 $routes-options(product, static function () { // 如需处理普通的非预检 OPTIONS 请求可在此实现逻辑 $response response(); $response-setStatusCode(204); $response-setHeader(Allow:, OPTIONS, GET, POST, PUT, PATCH, DELETE); return $response; }); $routes-options(product/(:any), static function () {}); });这里$routes-options(product/(:any), ...)覆盖了资源路由的所有子路径预检$routes-options(product, ...)中演示了如何处理非预检的普通 OPTIONS 请求返回204并附带Allow头。方式二在 Config/Filters.php 中按 URI 路径设置也可以改用app/Config/Filters.php的$filters属性按 URI 模式匹配示例源自 cors/002.phpnamespace Config; use CodeIgniter\Config\Filters as BaseFilters; class Filters extends BaseFilters { public array $filters [ cors [ before [api/*], after [api/*], ], ]; }同样必须补充 OPTIONS 路由示例源自 cors/003.phpuse CodeIgniter\Router\RouteCollection; $routes-group(, [filter cors], static function (RouteCollection $routes): void { $routes-options(api/(:any), static function () {}); });注意此方式将过滤器配置在路由之外的$filters属性中所有匹配api/*的请求无论 GET、POST 还是 OPTIONS都会经过cors过滤器。多配置cors:api与过滤器参数当不同路由组需要不同策略时可为app/Config/Cors.php添加新的属性作为独立配置。属性名即配置名例如新增$api示例源自 cors/004.phpnamespace Config; use CodeIgniter\Config\BaseConfig; class Cors extends BaseConfig { // ... $default ... public array $api [ allowedOrigins [https://app.example.com], allowedOriginsPatterns [], supportsCredentials true, allowedHeaders [Authorization, Content-Type], exposedHeaders [], allowedMethods [GET, POST, PUT, DELETE], maxAge 7200, ]; }然后在路由过滤器参数中以cors:api的形式指定该配置名示例源自 cors/005.phpuse CodeIgniter\Router\RouteCollection; $routes-group(api, [filter cors:api], static function (RouteCollection $routes): void { $routes-resource(user); $routes-options(user, static function () {}); $routes-options(user/(:any), static function () {}); });其底层机制是过滤器before()收到参数数组$arguments后调用CorsService::factory($arguments[0])按名字取出对应配置见 system/Filters/Cors.php 与 system/HTTP/Cors.php 的factory()。同样的参数语法也可用于$filters属性例如cors:api [before [api/*], after [api/*]]即文档中提到的 过滤器参数 功能自 4.4.0 起支持4.6.0 起spark输出表中会显示过滤器参数。验证配置spark routes 与 spark filter:check配置完成后可用spark命令核对路由与过滤器php spark routes该命令会列出全部路由及其绑定的过滤器含闭包路由、自动路由与过滤器信息详见 路由文档。由于路由正则表达式可能导致过滤器显示不准文档还推荐使用更精确的过滤器检查命令详见 过滤器文档php spark filter:check get /输出会以表格形式呈现Method | Route | Before Filters | After Filters并列出实际执行的过滤器类名自 4.6.0 起同时显示过滤器参数。源码级原理CodeIgniter\HTTP\Cors 的工作方式CORS 辅助类的完整实现在 system/HTTP/Cors.php以下三个公开方法对应文档类参考部分isPreflightRequest(IncomingRequest $request): bool判断请求是否为预检请求判定条件只有两个源码 L80-L84return $request-is(OPTIONS) $request-hasHeader(Access-Control-Request-Method);即请求方法为OPTIONS且携带Access-Control-Request-Method头。这正好被 tests/system/HTTP/CorsTest.php 中的testIsPreflightRequestTrue/False用例覆盖仅有OPTIONS方法但无该头时返回false。handlePreflightRequest(RequestInterface $request, ResponseInterface $response): ResponseInterface处理预检请求源码 L89-L103。流程为设置响应状态码204 No Content调用setAllowOrigin()校验请求 Origin 并输出Access-Control-Allow-Origin仅当Origin 校验通过响应中已有该头时才依次输出Access-Control-Allow-Headers、Access-Control-Allow-Methods、Access-Control-Max-Age与如启用Access-Control-Allow-Credentials。Origin 匹配有三个分支源码 L129-L170与测试用例一一对应单一 OriginallowedOrigins恰好 1 个且无正则时直接回显该值测试testHandlePreflightRequestSingleAllowedOrigin多个 Origin从请求的Origin头精确匹配命中则回显该 Origin 并追加Vary: Origin未命中则不输出任何 CORS 头测试testHandlePreflightRequestMultipleAllowedOriginsAllowed/NotAllowed正则模式依次用#\Apattern\z#匹配命中则回显并追加Vary: Origin测试testHandlePreflightRequestAllowedOriginsPatternsAllowed/NotAllowed。Vary: Origin的存在意义在于响应内容随 Origin 变化必须告知 CDN/代理缓存按 Origin 区分缓存条目防止跨源缓存污染。addResponseHeaders(RequestInterface $request, ResponseInterface $response): ResponseInterface为普通非预检跨源请求添加响应头源码 L209-L219设置Access-Control-Allow-Origin后若校验通过再补充Access-Control-Allow-Credentials与Access-Control-Expose-Headers。注意普通请求不会输出Allow-Headers/Allow-Methods测试testAddResponseHeadersSingleAllowedOriginSimpleRequest已断言这两个头不存在。过滤器如何衔接before / after 与 Vary 头system/Filters/Cors.php 的before()中若判定为预检请求则直接返回handlePreflightRequest()的结果并短路后续控制器执行同时无论预检还是普通 OPTIONS 请求都会追加Vary: Access-Control-Request-Method头源码注释解释若有 CDN 等中间缓存普通 OPTIONS 与有效预检请求会被分开缓存避免错误命中。after()则通过hasResponseHeaders()判断响应是否已被例如其他过滤器注入过 CORS 头避免重复添加——这正是 v4.6.1 更新日志 中修复其他过滤器在 before 阶段返回响应对象时 CORS 头未添加问题的设计所在。类参考速查以下为 system/HTTP/Cors.php 对外公开的 API 摘要方法签名说明addResponseHeadersaddResponseHeaders(RequestInterface $request, ResponseInterface $response): ResponseInterface为跨源请求添加 CORS 响应头handlePreflightRequesthandlePreflightRequest(RequestInterface $request, ResponseInterface $response): ResponseInterface处理预检请求返回204及全套 CORS 头isPreflightRequestisPreflightRequest(IncomingRequest $request): bool判断请求是否为预检请求OPTIONSAccess-Control-Request-Method除此之外构造函数与factory(string $configName default)支持直接以配置数组或CorsConfig实例初始化hasResponseHeaders()供过滤器判断头部是否已设置。完整行为可对照单元测试 tests/system/HTTP/CorsTest.php 阅读其中覆盖了单源/多源/正则匹配、凭据、暴露头、Vary头合并等全部场景。小结在 CodeIgniter 4 中启用 CORS 遵循一条固定链路先在 app/Config/Cors.php 配置$default或自定义命名配置再在 app/Config/Routes.php / app/Config/Filters.php 绑定cors或cors:配置名过滤器最后务必为路由补充 OPTIONS 预检路由。配置完成后用php spark routes与php spark filter:check验证配合本文给出的源码分支与测试用例即可快速定位 Origin 未匹配、凭据与通配符冲突、缓存Vary头缺失等绝大多数跨域问题。赞分享后端Web框架【免费下载链接】CodeIgniter4Open Source PHP Framework (originally from EllisLab)项目地址https://gitcode.com/gh_mirrors/co/CodeIgniter4点击查看免费下载相关推荐如何快速入门EasyRec5分钟搭建你的第一个推荐模型如何快速入门EasyRec5分钟搭建你的第一个推荐模型 EasyRec是一个功能强大的大规模推荐算法框架专为快速构建高效推荐系统而设计。无论你是推荐系统新手后端机器学习深度学习Automa跨域资源共享CORS配置与预检请求处理Automa跨域资源共享CORS配置与预检请求处理 概述 在Web开发中跨域资源共享CORSCross Origin Resource SharingRPA工作流自动化浏览器控制网页爬虫WinterJS 跨域资源共享CORS配置与预检请求处理WinterJS 跨域资源共享CORS配置与预检请求处理 什么是跨域资源共享CORS 在现代Web开发中浏览器出于安全考虑实施了同源策略Same Or创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考