跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何解决Hyperf中跨域CORS配置无效的问题_在中间件中设置Access-Control头信息

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

相关文章