回應


####

HTTP 回應

  • 建立回應
  • 重定向
    • 重定向到命名路由
    • 重定向到控制器行為
    • ##重定向到外部網域名稱
    • 重新導向並使用快閃記憶體的Session 資料
  • 其他回應類型
    • 視圖回應
    • JSON 回應
    • #檔案下載
    • 檔案回應
  • 回應巨集

#建立回應

字串& 陣列

所有路由和控制器處理完業務邏輯之後都會傳回一個傳送到使用者瀏覽器的回應,Laravel 提供了多種不同的方式來回傳回應,最基本的回應就是從路由或控制器傳回一個簡單的字串,框架會自動將這個字串轉換為一個完整的HTTP 回應:

Route::get('/', function () { 
   return 'Hello World';
  });

除了從路由或控制器傳回字串之外,還可以傳回數組。框架會自動將陣列轉換為 JSON 回應:

Route::get('/', function () { 
   return [1, 2, 3];
 });

{tip} 你知道也可以從路由或控制器回傳 Eloquent 集合 嗎?他們也會被自動轉換為 JSON 回應。

Response 物件

通常,我們不會只是從路由動作簡單地傳回字串和數組,大多數情況下,都會回傳一個完整的 

Illuminate\Http\Response

實例或視圖。 傳回完整的

Response

實例允許你自訂回應的 HTTP 狀態碼和回應頭資訊。 Response 實例繼承自Symfony\Component\HttpFoundation\Response 類, 此類別提供了各種建構HTTP 回應的方法:

Route::get('home', function () { 
   return response('Hello World', 200)                  
          ->header('Content-Type', 'text/plain');
 });

新增回應頭

大部分的回應方法都是可鍊式呼叫的,使得建立回應實例的過程更具可讀性。例如,你可以在回應傳回給使用者前使用

header

方法為其新增一系列的頭資訊:

return response($content)         
   ->header('Content-Type', $type)            
   ->header('X-Header-One', 'Header Value')            
   ->header('X-Header-Two', 'Header Value');
或者,你可以使用

withHeaders

方法來指定要新增到回應的頭資訊數組:

return response($content)          
  ->withHeaders([              
    'Content-Type' => $type,                
    'X-Header-One' => 'Header Value',                
    'X-Header-Two' => 'Header Value',            
 ]);

#

快取控制中間件

Laravel 內建了一個 cache.headers 中間件,可以用來快速設定路由組 Cache-Control 頭資訊。如果在指令集中宣告了etag,Laravel 會自動將ETag 識別碼設定為回應內容的MD5 雜湊值:

Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function() {  
  Route::get('privacy', function () {      
    // ...   
   });    
Route::get('terms', function () {     
   // ...    
  });
});

加入Cookies 到回應

你可以使用回應上的cookie 方法輕鬆地將回應增加Cookies。例如,你可以像這樣使用cookie 方法產生一個cookie 並輕鬆地將其附加到回應上:

return response($content)              
  ->header('Content-Type', $type)                
  ->cookie('name', 'value', $minutes);

cookie 方法也接受一些不太頻繁使用的參數。通常,這些參數與原生PHP 的setcookie 方法的參數有著相同的目的和意義:

->cookie($name, $value, $minutes, $path, $domain, $secure, $httpOnly)

或者,你可以使用Cookie facade “佇列”, Cookie以附加到應用程式的傳出回應。 queue 方法接受一個 Cookie 實例或建立 Cookie 實例所需的參數。這些cookie 在傳送到瀏覽器之前會附加到傳出回應中:

Cookie::queue(Cookie::make('name', 'value', $minutes));
Cookie::queue('name', 'value', $minutes);

Cookies & 加密

預設情況下,Laravel 產生的所有Cookie 都是經過加密和簽名,因此不能被客戶端修改或讀取。如果你想要應用程式產生的部分Cookie 不被加密,那麼可以使用在app/Http/Middleware 目錄中App\Http\Middleware\EncryptCookies 中介軟體的 $except 屬性:

/**
 * 不需要被加密的cookies名称
 *
 * @var array
 */
 protected $except = [  
   'cookie_name',
  ];

#重定向

重定向回應是Illuminate\Http \RedirectResponse 類別的實例,並且包含使用者需要重新導向至另一個URL 所需的頭資訊。 Laravel 提供了幾種方法用於產生 RedirectResponse 實例。其中最簡單的方法是使用全域輔助函數 redirect

Route::get('dashboard', function () { 
   return redirect('home/dashboard');
 });

有時你可能希望將使用者重新導向到先前的位置,例如提交的表單無效時。這時你可以使用全域輔助函數 back 來執行此操作。由於這個功能利用了會話控制,請確保呼叫back 函數的路由使用web 中間件組或所有Session 中間件:

Route::post('user/profile', function () {  
  //验证请求   
  return back()->withInput();
});

#

重定向到命名路由

如果呼叫不帶參數的輔助函數 redirect 時,會傳回 Illuminate\Routing\Redirector 實例。這個實例允許你呼叫 Redirector 上的任何方法。例如為命名路由產生RedirectResponse,可以使用route 方法:

return redirect()->route('login');

如果路由中有參數,可以將其作為第二個參數傳遞到 route 方法:

// 对于具有以下 URI 的路由: profile/{id}
return redirect()->route('profile', ['id' => 1]);

透過Eloquent 模型填充參數

如果你要重定向到使用從Eloquent 模型填充「ID」參數的路由,可以簡單地傳遞模型本身。 ID 會被自動擷取:

//对于具有以下 URI 的路由: profile/{id}
return redirect()->route('profile', [$user]);

如果你想要自訂這個路由參數中的預設參數名,需要重寫模型實例上的getRouteKey 方法:

/**
 * 获取模型的路由键
 *
 * @return mixed
 */
 public function getRouteKey(){ 
    return $this->slug;
 }

跳到控制器Action

也可以產生到controller action 的跳躍。要達到這個目的,只要把 控制器 和 action 的名稱傳遞給 action 方法。記住,不需要傳遞控制器的全部命名空間,Laravel 的RouteServiceProvider 會自動將其設定為基本控制器的命名空間:

return redirect()->action('HomeController@index');

如果控制器路由需要參數,可以將其作為action 方法的第二個參數:

return redirect()->action(  
  'UserController@profile', ['id' => 1]
 );

跳到外部網域名稱

有時候你需要跳到應用程式外的網域。呼叫away 方法可以達到此目的,它會建立一個不帶有任何額外的URL 編碼、有效性校驗和檢查的RedirectResponse 實例:

return redirect()->away('https://www.google.com');

帶有傳送Session 值的跳到

#跳到新的URL 的同時傳送資料給session 是很常見的。通常會在成功執行一個動作並傳送訊息給 session 之後這樣做。為了方便起見,你可以建立一個 RedirectResponse 實例並在鍊式方法呼叫中將資料傳送給 session :

Route::post('user/profile', function () { 
   // Update the user's profile...    
   return redirect('dashboard')->with('status', 'Profile updated!');
 });

在使用者跳轉後,可以顯示 session 中的傳送資料。例如使用Blade syntax :

@if (session('status'))    
  <div class="alert alert-success">        
       {{ session('status') }}    
  </div>
@endif

#其它的回應類型

response 助理可以用於生成其它類型的回應實例。當也帶參數呼叫 response 助手時,傳回 Illuminate\Contracts\Routing\ResponseFactory contract 的一個實作。這個契約提供了幾個用來產生回應的方法:

#

視圖回應

如果需要把視圖當作回應內容回傳的同時,控制回應狀態和頭訊息,就需要呼叫view 方法:

return response()            
    ->view('hello', $data, 200)            
    ->header('Content-Type', $type);

如果不需要傳遞自訂的HTTP 狀態碼和自訂頭訊息,也可以使用全域的 view 輔助函數。

JSON 回應

#json 自動將Content-Type頭資訊設定為application/json,同時使用PHP 的 json_encode 函數將給定的陣列轉換為JSON :

return response()->json([  
  'name' => 'Abigail',    
  'state' => 'CA'
 ]);

如果想要建立JSONP 回應,可以結合 withCallback  方法使用json 方法:

return response()           
 ->json(['name' => 'Abigail', 'state' => 'CA'])            
 ->withCallback($request->input('callback'));

檔案下載

download 方法可以用來產生強制使用者瀏覽器下載給定路徑檔案的回應。 download 方法檔案名稱作為其第二個參數,它將作為使用者下載檔案的檔案名稱。最後,你可以傳遞 HTTP 頭資訊陣列作為其第三個參數:

return response()->download($pathToFile);
return response()->download($pathToFile, $name, $headers);
return response()->download($pathToFile)->deleteFileAfterSend();

{note} 用於管理檔案下載的 Symfony HttpFoundation 要求下載的檔案有一個 ASCII 檔案名稱。

流下載

有時,你可能希望將給定操作的字串回應轉換為下載回應,而不需要將其寫入磁碟。此時可以使用 streamDownload 方法。這個方法接受回呼、檔案名稱和可選的頭資訊數組作為參數:

return response()->streamDownload(function () { 
   echo GitHub::api('repo')              
     ->contents()                
     ->readme('laravel', 'laravel')['contents'];
 }, 'laravel-readme.md');

檔案回應

##file 方法用於直接在使用者瀏覽器中顯示一個圖片或PDF 之類的文件,而不是下載。這個方法接受檔案路徑作為第一個參數,頭資訊數組作為第二個參數:

return response()->file($pathToFile);
return response()->file($pathToFile, $headers);

回應巨集 如果你想要定義一個自訂的可以在多個路由和控制器中復用的回應,可以使用Response

門面上的 方法編寫如下程式碼:
<?php
   namespace App\Providers;
   use Illuminate\Support\ServiceProvider;
   use Illuminate\Support\Facades\Response;
   class ResponseMacroServiceProvider extends ServiceProvider{   
    /**
     * 注册应用程序的响应宏
     *
     * @return void
     */   
    public function boot()  
      {        
          Response::macro('caps', function ($value) {         
          return Response::make(strtoupper($value));        
       });   
      }
   }
######macro### 方法接受一個名稱作為第一個參數,閉包函數作為的第二個參數。回應巨集的閉包在###ResponseFactory### 實作類別或輔助函式###response### 中呼叫巨集名稱的時候被執行:###
return response()->caps('foo');
###本文章首發在###LearnKu. com### 網站上。 ######