Laravel怎么获取请求头信息_Laravel如何自定义Header【笔记】

2次阅读

laravel 中应统一使用 request()->header() 获取请求头,它自动处理大小写不敏感、代理头标准化及环境兼容性;自定义响应头须通过中间件设置 Response 实例;队列任务中无法访问请求头,需提前提取关键值传参;nginx/apache 配置(如 underscores_in_headers on)直接影响 header 透传。

Laravel怎么获取请求头信息_Laravel如何自定义Header【笔记】

直接用 request()->header() 拿请求头,别碰 $_SERVER

Laravel 的 request()->header() 是唯一推荐方式。它自动处理大小写不敏感、X-forwarded-For 等代理头的标准化,而直接读 $_SERVER['http_X_CUSTOM_HEADER'] 会漏掉被 Apache/Nginx 重写的头(比如把 X-Api-Key 变成 HTTP_X_API_KEY),且在 CLI 或 swoole 环境下行为不一致。

常见错误现象:request()->header('X-Api-Key') 返回 NULL,但 postman 明明发了——大概率是 Nginx 默认剥离了带下划线的 header,或用了 fastcgi_param 未显式透传。

  • request()->header('X-Api-Key'),不是 request()->headers->get('X-Api-Key')(后者也能用,但前者更直觉、自动 trim)
  • 所有 header 名不区分大小写,request()->header('x-api-key')request()->header('X-API-KEY') 效果一样
  • 如果 header 值是数组(如多个 cookie),request()->header() 默认只返回第一个;要全量用 request()->header('Cookie', null, true)(第三个参数设为 true

自定义 Header 必须在中间件里加,不能在控制器里 header()

Laravel 响应头必须通过 Response 实例设置,控制器里调 header('X-Trace-ID', 'abc123') 是无效的——PHP 的原生 header() 在 Laravel 的响应生命周期中早已失效,甚至可能触发 “headers already sent” 错误。

使用场景:需要统一加审计 ID、版本标识、CSP 策略等全局响应头。

  • 新建中间件:php artisan make:middleware AddCustomHeader
  • handle() 里写:$response = $next($request); $response->headers->set('X-Trace-ID', Str::uuid()); return $response;
  • 注册到 $middlewareGroups['web']$middleware,取决于是否需要对 API 路由生效
  • 避免在中间件里做耗时操作(比如查 DB 生成 header 值),否则拖慢所有请求

Request::header() 在队列任务里拿不到,因为没 HTTP 上下文

队列任务运行在 CLI 进程,没有原始请求头。哪怕你把 Request 对象序列化传进去,header() 方法也会返回空——这不是 bug,是设计使然。试图在 Job 构造函数里接收 Request 并缓存 header,等于埋雷。

正确做法是在发起队列前,把真正需要的 header 值抽出来,作为参数显式传入:

  • 比如需要记录请求来源:ProcessOrderJob::dispatch($order, request()->header('X-Forwarded-For'))
  • 不要传整个 request()$request->all(),容易序列化失败或泄露敏感字段
  • 如果 header 值本身依赖运行时计算(如签名验证结果),应在 dispatch 前完成验证,再把结果传入

Nginx/Apache 配置影响 header 透传,特别是带下划线的 key

Apache 默认丢弃含下划线的 header(如 X_Api_Key),Nginx 默认把下划线转为短横线,还可能因 underscores_in_headers off 直接忽略。这是线上环境最常被忽略的环节——代码没问题,配置卡脖子。

典型错误现象:本地开发能拿到 X-Auth-Token,上线后始终 null;或者 curl -H "X_Api_Key: abc" ... 在服务器上完全收不到。

  • Nginx:确保配置中有 underscores_in_headers on;,并在 location 块里显式透传:proxy_set_header X-Api-Key $http_x_api_key;
  • Apache:在虚拟主机里加 SetEnvIfNoCase ^X-Api-Key$ ^(.*)$ X_API_KEY=$1,再在 Laravel 中用 request()->server('HTTP_X_API_KEY')(不推荐,仅作兜底)
  • 测试是否生效:用 curl -I -H "X-Test: 123" https://yoursite.com,然后在控制器里 Log::info(request()->header('X-Test')) 查日志

实际项目里,header 丢失往往卡在 Nginx 层或队列上下文切换,而不是 Laravel 写法本身。多看日志,少猜逻辑。

text=ZqhQzanResources