Hyperf中CorsMiddleware失效主因是OPTIONS预检请求被路由层拦截返回405,未进入中间件;需全局注册中间件、启用auto_options、校验Origin白名单,并从Context获取Response对象。
Hyperf里加了
却没生效,基本不是头写错了,而是中间件压根没执行——尤其是
预检请求被路由层拦截后直接返回405,连中间件的边都没摸到。
OPTIONS请求卡在路由层,返回405而不是进中间件
Hyperf默认不自动注册
路由。浏览器发来预检请求时,如果当前路径没定义
方法,
会抛出
,响应405,整个中间件链就此中断。
检查日志里有没有
或
确认你访问的路径(比如
)是否在路由中显式声明过
,哪怕只写
Hyperf 3.1+ 可启用
:在
里设
,它会自动为所有已注册的
等路径补上
中间件没挂对位置,只对部分路由起作用
如果只通过
注解或
数组配给某个
,那未覆盖的路径(尤其是根路径
、健康检查
等)照样掉进405陷阱。
PHP数据库链接类(PDO+Access)
PHP数据库链接类(PDO+Access)
下载
必须把中间件注册到全局:在
的
数组顶层添加,例如:
别写成
这种嵌套错误格式,应是
若同时用了鉴权中间件(如
),
必须放在它前面——否则预检请求先被鉴权拦住,根本走不到CORS逻辑
Response对象用错实例,Header写不进真实响应
很多示例直接
,这会创建一个脱离上下文的新对象,后续
操作全白费,Header不会出现在最终HTTP响应里。
必须从上下文取当前响应:
所有头操作要链式调用后,再写回上下文:
处理
分支时,除了
,还必须
,否则Swoole协程可能卡住连接
生产环境禁用
+
组合,浏览器明确拒绝——得根据
头动态匹配白名单并回写具体域名
最常被忽略的是
开关和
这两处;一旦漏掉,无论头写得多规范,都只是在往空气里塞Header。
CorsMiddlewareOPTIONSOPTIONSOPTIONShyperf/routingMethodNotAllowedHttpExceptionMethodNotAllowedHttpException405 Method Not Allowed/api/userOPTIONSRouter::addRoute('OPTIONS', '/api/user', ...)auto_optionsconfig/autoload/routes.php'auto_options' => trueGET/POST/PUTOPTIONSCorsMiddleware@MiddlewaremiddlewareRouter::addGroup//pingconfig/autoload/middlewares.php'http'App\Middleware\CorsMiddleware::class['http' => ['App\Middleware\CorsMiddleware']]'http' => [App\Middleware\CorsMiddleware::class]AuthMiddlewareCorsMiddlewarenew \Hyperf\HttpMessage\Server\Response()withHeader()$response = Context::get(ResponseInterface::class)Context::set(ResponseInterface::class, $response->withHeader(...))OPTIONSwithStatus(204)withBody(new SwooleStream(''))Access-Control-Allow-Origin: *Access-Control-Allow-Credentials: trueOriginauto_optionsContext::get(ResponseInterface::class)