javck
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: laravel --- # 回應Response ![](https://i.imgur.com/ashYLZx.jpg) ![](https://i.imgur.com/SD6JuF5.jpg) ## 建立回應 ### 字串 & 陣列 所有路由和控制器處理完業務邏輯之後都會回傳一個發送到用戶瀏覽器的回應,Laravel 提供了多種不同的方式來進行回應,最基本的回應就是從路由或控制器回傳一個簡單的字串,框架會自動將這個字串轉化為一個完整的 HTTP 回應: ``` Route::get('/', function () { return 'Hello World'; }); ``` 除了從路由或控制器返回字串之外,還可以回傳陣列。框架會自動將陣列轉化為一個 JSON 回應: ``` Route::get('/', function () { return [1, 2, 3]; }); ``` > 技巧: > > 你知道還可以從路由或控制器返回 Eloquent 集合嗎?它們也會被自動轉化為 JSON 回應 ### 回應對象 通常,我們並不只是從路由方法單純回傳字串和陣列。相對的都會回傳一個完整的 Illuminate\Http\Response 實例或視圖 返回完整的 Response 實例允許你自定義回應的 HTTP 狀態碼和 headers。 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() 去指定一個 headers 陣列被加在回應上 ``` 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 Hash 值: ``` Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () { Route::get('/privacy', function () { // ... }); Route::get('/terms', function () { // ... }); }); ``` ### 附加 Cookies 到回應 你可以使用回應上的 cookie() 輕鬆地為回應增加 Cookies。例如你可以像這樣使用 cookie() 生成一個 Cookie 並輕鬆地將其附加到回應上。你應該透過這個方法傳送 name. value 和 cookie 應該被視為有效的分鐘數 ``` return response('Hello World')->cookie( 'name', 'value', $minutes ); ``` cookie() 還接受一些不太頻繁使用的參數。通常這些參數與原生PHP的 setcookie() 的參數有着相同的目的和含義: ``` return response('Hello World')->cookie( 'name', 'value', $minutes, $path, $domain, $secure, $httpOnly ); ``` 假如你想要確保有一個 Cookie 能透過發出的回應被送出,但是你還沒有回應的實例的話。你能夠使用 Cookie Facade 來隊列這些要附加的 Cookies 直到被送出。 queue() 接受所有建立 cookie 實例所需要的參數,這些 cookies 將會在送到瀏覽器之前附加在送出的回應上 ``` use Illuminate\Support\Facades\Cookie; Cookie::queue('name', 'value', $minutes); ``` #### 生成 Cookie 實例 假如你想要生成一個 Symfony\Component\HttpFoundation\Cookie 實例,並希望它能在稍晚被附加在回應實例上,你應該使用全域的 cookie() 。 這個 Cookie 將不會被傳回到瀏覽器除非它被附加在一個回應實例上 ``` $cookie = cookie('name', 'value', $minutes); return response('Hello World')->cookie($cookie); ``` #### 提早讓 Cookie 過期 你可以對回應呼叫 withoutCookie() 來透過使之過期的方式來移除一個 Cookie `return response('Hello World')->withoutCookie('name');` 假如你仍未得到回應實例,你可以透過 Cookie Facade 的 queue() 來讓 Cookie 提早過期 `Cookie::queue(Cookie::forget('name'));` ### Cookies & Encryption 預設情況下,Laravel 生成的所有 Cookie 都是經過加密和簽名,因此不能被客戶端修改或者讀取。 如果你想要應用生成的部分 Cookie 不被加密,那可以透過在 app/Http/Middleware 資料夾中 App\Http\Middleware\EncryptCookies 中介層的 $except 屬性 ``` /** * The names of the cookies that should not be encrypted. * * @var array */ protected $except = [ 'cookie_name', ]; ``` ## 轉址 轉址回應是 Illuminate\Http\RedirectResponse 類別的實例,並且包含用戶需要轉址至另一個 URL 所需的 header。Laravel 提供了幾種方法用於生成 RedirectResponse 實例。其中最簡單的方法是使用全域幫助函式 redirect() ``` Route::get('/dashboard', function () { return redirect('home/dashboard'); }); ``` 有時候你可能希望將用戶轉址到前一個網址,比如提交的表單有問題時。這時你可以使用全域幫助函式 back() 來執行此操作。由於這個功能是透過 Session,請確保呼叫 back() 的路由有分配 web 中介層群組 ``` Route::post('/user/profile', function () { // Validate the request... 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 Models 充填參數 如果你要轉址到使用 Eloquent 模型填充 id 參數的路由,可以直接傳遞模型本身,而 id 會被自動抓出 ``` // 對應的路由 URI: /profile/{id} return redirect()->route('profile', [$user]); ``` 如果你想要自定義這個路由參數中的預設參數名稱,需要覆寫模型實例上的 getRouteKey() 或者指定路由參數(/profile/{id:slug}) ``` /** * 取得模型的路由 key. * * @return mixed */ public function getRouteKey() { return $this->slug; } ``` ### 轉址到控制器方法 你還可以生成到控制器方法的轉址。要達到這個目的,只要把控制器和方法的名稱傳遞給 action() ``` use App\Http\Controllers\UserController; return redirect()->action([UserController::class, 'index']); ``` 假如你的控制器路由需要參數,你可以將之作為第二參數傳進 action() ``` return redirect()->action( [UserController::class, 'profile'], ['id' => 1] ); ``` ### 轉址到外部網域 有時候你需要轉址到應用外的網域。呼叫 away() 可以達到此目的,它會創建一個不帶有任何額外的 URL 編碼、有效性驗證檢查的 RedirectResponse 實例 `return redirect()->away('https://www.google.com');` ### 轉址並使用 Session 資料 轉址到新的 URL 的同時傳送資料給 Session 是很常見的。 通常會在成功執行一個動作並傳送訊息給 session,以便在新的頁面可以顯示這個訊息。為了方便起見,你可以創建一個 RedirectResponse 實例並接著在後面呼叫相關方法來將數據傳送給 Session : ``` Route::post('/user/profile', function () { // ... return redirect('dashboard')->with('status', 'Profile updated!'); }); ``` 在使用者被轉址後,你就能從 Session 取出訊息並顯示在畫面上。比如這裡透過 Blade 來呈現: ``` @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif ``` ### 轉址並帶著先前輸入資料 你可以使用 RedirectRespoonse 實例的 withInput() 來將當前請求的輸入資料存入Session,以便再回到先前驗證有錯誤表單時可做為預設值。 `return back()->withInput();` ## 其他回應類型 response() 幫助函式可用於生成其它類型的回應實例。當不傳入任何參數去呼叫 response() 時,會回傳 Illuminate\Contracts\Routing\ResponseFactory contract 的一個實現。這個契約提供了幾個用於生成回應的方法: ### 視圖回應 如果需要把視圖作為回應內容返回的同時,控制回應狀態和 headers,就需要呼叫 view() ``` return response() ->view('hello', $data, 200) ->header('Content-Type', $type); ``` 如果不需要傳遞自定義的 HTTP 狀態碼和 headers,還可以直接使用全域的 view() ### JSON 回應 json() 會自動將 header 的 Content-Type 設定為 application/json,同時使用 PHP 的 json_encode() 將傳入的陣列轉換為 JSON ``` return response()->json([ 'name' => 'Abigail', 'state' => 'CA', ]); ``` 假如你想要生成一個 JSONP 回應,你可以在 json() 後面再接一個 withCallback() ``` return response() ->json(['name' => 'Abigail', 'state' => 'CA']) ->withCallback($request->input('callback')); ``` ### 檔案下載 download() 可用於生成一個回應,強制用戶瀏覽器去下載指定路徑的檔案。 download() 將檔案名稱作為其第二個參數,它將作為用戶下載檔案後的新檔名。最後你可以傳遞 HTTP header 陣列作為其第三個參數: ``` return response()->download($pathToFile); return response()->download($pathToFile, $name, $headers); ``` >注意: > >用於管理檔案下載的 Symfony HttpFoundation 要求下載的檔案要有一個 ASCII 檔名。 #### 流下載 有時你可能希望將傳入操作的字串回應轉換為可下載回應,而不需要將之寫入磁碟。此時可以使用 streamDownload()。這個方法接受 Closure、檔案名稱和非必須提供的 header 陣列作為參數 ``` use App\Services\GitHub; return response()->streamDownload(function () { echo GitHub::api('repo') ->contents() ->readme('laravel', 'laravel')['contents']; }, 'laravel-readme.md'); ``` ### 檔案回應 file() 用於直接在用戶瀏覽器顯示一個圖片或 PDF 之類的檔案,而不是下載。這個方法接受檔案路徑作為第一個參數,header 陣列作為第二個參數 ``` return response()->file($pathToFile); return response()->file($pathToFile, $headers); ``` ## 回應宏 如果你想要定義一個自定義的可以在多個路由和控制器中重複使用的回應,可以使用 Response Facade 上的 macro() 。你一般會在服務供應器的 boot() 方法寫以下程式,尤其是在 App\Providers\AppServiceProvider ``` <?php namespace App\Providers; use Illuminate\Support\Facades\Response; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Response::macro('caps', function ($value) { return Response::make(strtoupper($value)); }); } } ``` macro() 接受一個名稱作為第一個參數,Closure 作為第二個參數。回應宏的 Closure 在 ResponseFactory 實現類別或幫助函式 response() 中呼叫宏名稱的時候被執行 `return response()->caps('foo');`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully