如何正確地在 Response 加 Header(1)
前一陣子,朋友在社群分享小知識。
$routeMiddleware 裡面的 middleware 加上 $header 的話會有問題,要在 $middleware 宣告才能保證生效
因為剛好正在研究 Laravel 原始碼,所以就認真翻了一下。
Response header 是在分析 bootstrap 流程有提到 index.php
的這行程式碼才會送出:
$response->send(); |
因此只要了解 $response 如何建構,以及 Pipeline 經過了哪些關卡、被做了哪些修改,就能知道真正問題點在哪了。
Response 如何被建構出來的
在 middleware 裡,我們會預期 $next($request)
回來的結果會是 [Response][] 物件。這可以在 Router 裡找到蛛絲馬跡。在分析 Routing 時,有提到 runRouteWithinStack()
的實作,裡面在執行 Pipeline 的程式碼如下:
return (new Pipeline($this->container)) |
根據 Pipeline 的分析,$next($request)
拿到的結果,正是 prepareResponse()
的回傳結果。換句話說,它就是建構 Response 的方法。
回顧一下 prepareResponse()
的實作,事實上有機會對 Response 做處理的,只有下面這兩個方法:
$response->setNotModified(); |
在解析 Middleware 的實作細節的時候,有提到 Pipeline 會被使用兩次,一次是上面所說的,也就是朋友所提到的 $routeMiddleware;另一次則是 $middleware,也就是在 Http Kernel 的這段程式碼:
protected function sendRequestThroughRouter($request) |
而 dispatchToRouter()
一直到 runRouteWithinStack()
的 call stack 如下:
Kernel::dispatchToRouter(); |
這過程中,還有另一次 prepareResponse()
,但如同上面 runRouteWithinStack()
所說,其實對 header 並沒有特別修改什麼。
因此可以知道建構與 Pipeline 過程,理論上不會影響 response header。
今天先看建構過程與 Pipeline 流程是否有問題,明天再來看預設的 middleware 是否有偷偷對 header 做什麼處理。