響應(yīng)
響應(yīng)
HTTP 響應(yīng)
創(chuàng)建響應(yīng)
字符串 & 數(shù)組
所有路由和控制器處理完業(yè)務(wù)邏輯之后都會(huì)返回一個(gè)發(fā)送到用戶瀏覽器的響應(yīng),Laravel 提供了多種不同的方式來(lái)返回響應(yīng),最基本的響應(yīng)就是從路由或控制器返回一個(gè)簡(jiǎn)單的字符串,框架會(huì)自動(dòng)將這個(gè)字符串轉(zhuǎn)化為一個(gè)完整的 HTTP 響應(yīng):
Route::get('/', function () { return 'Hello World'; });
除了從路由或控制器返回字符串之外,還可以返回?cái)?shù)組??蚣軙?huì)自動(dòng)將數(shù)組轉(zhuǎn)化為一個(gè) JSON 響應(yīng):
Route::get('/', function () { return [1, 2, 3]; });
{tip} 你知道還可以從路由或控制器返回 Eloquent 集合 嗎?他們也會(huì)被自動(dòng)轉(zhuǎn)化為 JSON 響應(yīng)。
Response 對(duì)象
通常,我們并不只是從路由動(dòng)作簡(jiǎn)單返回字符串和數(shù)組,大多數(shù)情況下,都會(huì)返回一個(gè)完整的 Illuminate\Http\Response
實(shí)例或 視圖。
返回完整的 Response
實(shí)例允許你自定義響應(yīng)的 HTTP 狀態(tài)碼和響應(yīng)頭信息。 Response
實(shí)例 繼承自 Symfony\Component\HttpFoundation\Response
類, 該類提供了各種構(gòu)建 HTTP 響應(yīng)的方法:
Route::get('home', function () { return response('Hello World', 200) ->header('Content-Type', 'text/plain'); });
添加響應(yīng)頭
大部分的響應(yīng)方法都是可鏈?zhǔn)秸{(diào)用的,使得創(chuàng)建響應(yīng)實(shí)例的過(guò)程更具可讀性。例如,你可以在響應(yīng)返回給用戶前使用 header
方法為其添加一系列的頭信息:
return response($content) ->header('Content-Type', $type) ->header('X-Header-One', 'Header Value') ->header('X-Header-Two', 'Header Value');
或者,你可以使用 withHeaders
方法來(lái)指定要添加到響應(yīng)的頭信息數(shù)組:
return response($content) ->withHeaders([ 'Content-Type' => $type, 'X-Header-One' => 'Header Value', 'X-Header-Two' => 'Header Value', ]);
緩存控制中間件
Laravel 內(nèi)置了一個(gè) cache.headers
中間件,可以用來(lái)快速地為路由組設(shè)置 Cache-Control
頭信息。如果在指令集中聲明了 etag
,Laravel 會(huì)自動(dòng)將 ETag 標(biāo)識(shí)符設(shè)置為響應(yīng)內(nèi)容的 MD5 哈希值:
Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function() { Route::get('privacy', function () { // ... }); Route::get('terms', function () { // ... }); });
添加 Cookies 到響應(yīng)
你可以使用響應(yīng)上的 cookie
方法輕松地將為響應(yīng)增加 Cookies。例如,你可以像這樣使用 cookie
方法生成一個(gè) cookie 并輕松地將其附加到響應(yīng)上:
return response($content) ->header('Content-Type', $type) ->cookie('name', 'value', $minutes);
cookie
方法還接受一些不太頻繁使用的參數(shù)。通常,這些參數(shù)與原生 PHP 的 setcookie 方法的參數(shù)有著相同的目的和含義:
->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)
或者,你可以使用 Cookie
facade 「隊(duì)列」, Cookie
以附加到應(yīng)用程序的傳出響應(yīng)。 queue
方法接受一個(gè) Cookie
實(shí)例或創(chuàng)建 Cookie
實(shí)例所需的參數(shù)。 這些 cookie 在發(fā)送到瀏覽器之前會(huì)附加到傳出響應(yīng)中:
Cookie::queue(Cookie::make('name', 'value', $minutes)); Cookie::queue('name', 'value', $minutes);
Cookies & 加密
默認(rèn)情況下,Laravel 生成的所有 Cookie 都是經(jīng)過(guò)加密和簽名,因此不能被客戶端修改或讀取。 如果你想要應(yīng)用程序生成的部分 Cookie 不被加密,那么可以使用在 app/Http/Middleware
目錄中 App\Http\Middleware\EncryptCookies
中間件的 $except
屬性:
/** * 不需要被加密的cookies名稱 * * @var array */ protected $except = [ 'cookie_name', ];
重定向
重定向響應(yīng)是 Illuminate\Http\RedirectResponse
類的實(shí)例,并且包含用戶需要重定向至另一個(gè) URL 所需的頭信息。Laravel 提供了幾種方法用于生成 RedirectResponse
實(shí)例。其中最簡(jiǎn)單的方法是使用全局輔助函數(shù) redirect
:
Route::get('dashboard', function () { return redirect('home/dashboard'); });
有時(shí)候你可能希望將用戶重定向到之前的位置,比如提交的表單無(wú)效時(shí)。這時(shí)你可以使用全局輔助函數(shù) back
來(lái)執(zhí)行此操作。由于這個(gè)功能利用了 會(huì)話控制,請(qǐng)確保調(diào)用 back
函數(shù)的路由使用 web
中間件組或所有 Session 中間件:
Route::post('user/profile', function () { //驗(yàn)證請(qǐng)求 return back()->withInput(); });
重定向到命名路由
如果調(diào)用不帶參數(shù)的輔助函數(shù) redirect
時(shí),會(huì)返回 Illuminate\Routing\Redirector
實(shí)例。這個(gè)實(shí)例允許你調(diào)用 Redirector
上的任何方法。例如為命名路由生成 RedirectResponse
,可以使用 route
方法:
return redirect()->route('login');
如果路由中有參數(shù),可以將其作為第二個(gè)參數(shù)傳遞到 route
方法:
// 對(duì)于具有以下 URI 的路由: profile/{id} return redirect()->route('profile', ['id' => 1]);
通過(guò) Eloquent 模型填充參數(shù)
如果你要重定向到使用從 Eloquent 模型填充「ID」參數(shù)的路由,可以簡(jiǎn)單地傳遞模型本身。ID 會(huì)被自動(dòng)提?。?/p>
//對(duì)于具有以下 URI 的路由: profile/{id} return redirect()->route('profile', [$user]);
如果你想要自定義這個(gè)路由參數(shù)中的默認(rèn)參數(shù)名,需要重寫模型實(shí)例上的 getRouteKey
方法:
/** * 獲取模型的路由鍵 * * @return mixed */ public function getRouteKey(){ return $this->slug; }
跳轉(zhuǎn)到控制器 Action
還可以生成到 controller action 的跳轉(zhuǎn)。要達(dá)到這個(gè)目的,只要把 控制器 和 action 的名稱傳遞給 action
方法。記住,不需要傳遞控制器的全部命名空間,Laravel 的 RouteServiceProvider
會(huì)自動(dòng)將其設(shè)置為基本控制器的命名空間:
return redirect()->action('HomeController@index');
如果控制器路由需要參數(shù),可以將其作為 action
方法的第二個(gè)參數(shù):
return redirect()->action( 'UserController@profile', ['id' => 1] );
跳轉(zhuǎn)到外部域名
有時(shí)候你需要跳轉(zhuǎn)到應(yīng)用外的域名。調(diào)用 away
方法可以達(dá)到此目的,它會(huì)創(chuàng)建一個(gè)不帶有任何額外的 URL 編碼、有效性校驗(yàn)和檢查的 RedirectResponse
實(shí)例:
return redirect()->away('https://www.google.com');
帶有傳送 Session 值的跳轉(zhuǎn)
跳轉(zhuǎn)到新的 URL 的同時(shí) 傳送數(shù)據(jù)給 session 是很常見的。 通常會(huì)在成功執(zhí)行一個(gè)動(dòng)作并傳送消息給 session 之后這樣做。為了方便起見,你可以創(chuàng)建一個(gè) RedirectResponse
實(shí)例并在鏈?zhǔn)椒椒ㄕ{(diào)用中將數(shù)據(jù)傳送給 session :
Route::post('user/profile', function () { // Update the user's profile... return redirect('dashboard')->with('status', 'Profile updated!'); });
在用戶跳轉(zhuǎn)后,可以顯示 session 中的傳送數(shù)據(jù)。比如使用 Blade syntax :
@if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif
其它的響應(yīng)類型
response
助手可以用于生成其它類型的響應(yīng)實(shí)例。當(dāng)還帶參數(shù)調(diào)用 response
助手時(shí),返回 Illuminate\Contracts\Routing\ResponseFactory
contract 的一個(gè)實(shí)現(xiàn)。這個(gè)契約提供了幾個(gè)用于生成響應(yīng)的方法:
視圖響應(yīng)
如果需要把 視圖 作為響應(yīng)內(nèi)容返回的同時(shí),控制響應(yīng)狀態(tài)和頭信息,就需要調(diào)用 view
方法:
return response() ->view('hello', $data, 200) ->header('Content-Type', $type);
如果不需要傳遞自定義的 HTTP 狀態(tài)碼和自定義頭信息,還可以使用全局的 view
輔助函數(shù)。
JSON 響應(yīng)
json
自動(dòng)將 Content-Type
頭信息設(shè)置為 application/json
,同時(shí)使用 PHP 的 json_encode
函數(shù)將給定的數(shù)組轉(zhuǎn)換為 JSON :
return response()->json([ 'name' => 'Abigail', 'state' => 'CA' ]);
如果想要?jiǎng)?chuàng)建 JSONP 響應(yīng),可以結(jié)合 withCallback
方法使用 json
方法:
return response() ->json(['name' => 'Abigail', 'state' => 'CA']) ->withCallback($request->input('callback'));
文件下載
download
方法可以用于生成強(qiáng)制用戶瀏覽器下載給定路徑文件的響應(yīng)。 download
方法文件名作為其第二個(gè)參數(shù),它將作為用戶下載文件的文件名。最后,你可以傳遞 HTTP 頭信息數(shù)組作為其第三個(gè)參數(shù):
return response()->download($pathToFile); return response()->download($pathToFile, $name, $headers); return response()->download($pathToFile)->deleteFileAfterSend();
{note} 用于管理文件下載的 Symfony HttpFoundation 要求下載的文件有一個(gè) ASCII 文件名。
流下載
有時(shí),你可能希望將給定操作的字符串響應(yīng)轉(zhuǎn)換為下載響應(yīng),而不需要將其寫入磁盤。此時(shí)可以使用 streamDownload
方法。這個(gè)方法接受回調(diào)、文件名和可選的頭信息數(shù)組作為參數(shù):
return response()->streamDownload(function () { echo GitHub::api('repo') ->contents() ->readme('laravel', 'laravel')['contents']; }, 'laravel-readme.md');
文件響應(yīng)
file
方法用于直接在用戶瀏覽器顯示一個(gè)圖片或 PDF 之類的文件,而不是下載。這個(gè)方法接受文件路徑作為第一個(gè)參數(shù),頭信息數(shù)組作為第二個(gè)參數(shù):
return response()->file($pathToFile); return response()->file($pathToFile, $headers);
響應(yīng)宏
如果你想要定義一個(gè)自定義的可以在多個(gè)路由和控制器中復(fù)用的響應(yīng),可以使用 Response
門面上的 macro
方法。例如,在某個(gè) 服務(wù)提供者 的 boot
方法編寫如下代碼:
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Response; class ResponseMacroServiceProvider extends ServiceProvider{ /** * 注冊(cè)應(yīng)用程序的響應(yīng)宏 * * @return void */ public function boot() { Response::macro('caps', function ($value) { return Response::make(strtoupper($value)); }); } }
macro
方法接受一個(gè)名稱作為第一個(gè)參數(shù),閉包函數(shù)作為的第二個(gè)參數(shù)。響應(yīng)宏的閉包在 ResponseFactory
實(shí)現(xiàn)類或輔助函數(shù) response
中調(diào)用宏名稱的時(shí)候被執(zhí)行:
return response()->caps('foo');