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