
在開發 Laravel 專案的網站後台系統時,我必須預留一些欄位,讓管理者可以自由輸入 HTML 區塊或小段代碼。
這在內容管理系統(CMS)或 Landing Page Builder 類型的專案中非常常見,例如:
- 在頁面中插入一段追蹤代碼(如 GA、Meta Pixel)
- 在特定區塊自訂 HTML 結構
- 在產品描述區輸入
<ul>、<li>、或{}格式化文字
然而,從資料庫輸出這些內容時,畫面卻完全「不如預期」。
那些 <div>、{}、<script> 全部被吃掉、變成純文字。
原因其實不難理解:Laravel 的 Blade 模板引擎會自動對所有輸出進行 HTML 轉義(escape),以防範 XSS 攻擊。
但對我們這種必須允許「合法代碼」輸出的後台設計來說,這反而造成了麻煩。
Blade 模板為什麼會吃掉特殊符號?

Laravel 之所以會「吃掉」特殊符號,是因為它的 Blade 模板在輸出變數時,會自動進行 HTML 實體轉義(HTML Escaping)。
這是框架內建的防護機制,目的是防止惡意腳本(XSS)被注入到頁面中執行。
🧠 舉例說明:Laravel Blade 的輸出行為
舉例來說,我們在 Blade 中這樣寫:
{{ $message }}
而 $message 的內容是:
<p>Hello <b>World</b></p>
瀏覽器最後看到的結果其實是這樣:
<p>Hello <b>World</b></p>
也就是說,所有 <、>、{、} 都被轉成了 HTML 實體。
原因在於,Laravel 在底層其實會自動把 {{ }} 轉譯為:
<?php echo e($message); ?>
e() 這個函式(其實是 Illuminate\Support\helpers.php 中的 e())
會呼叫 PHP 原生的 htmlspecialchars() 來確保輸出的內容是安全的。
✅ 這樣做的好處
- 避免使用者輸入惡意
<script>被直接執行。 - 預設所有輸出都是「安全文字」。
⚠️ 但缺點也很明顯
- 當我們真的需要輸出 HTML 時(例如管理者填的內容),標籤都會被轉義。
- 某些動態代碼(像
{!! config('app.name') !!}或模板占位符)會被錯誤顯示。
✨ 這時候,我們就得出場用到本文的主角:
{!! $message !!}
實際解法:{!! $message !!} 與 {{ $message }} 的差異
在 Laravel 的 Blade 模板中,輸出變數主要有兩種寫法:
| 語法 | 是否自動轉義 | 適合用途 |
|---|---|---|
{{ $message }} | 會自動轉義 | 一般文字輸出,例如文章標題、使用者名稱 |
{!! $message !!} | 不會自動轉義 | 已經確認安全的 HTML、後台代碼區塊、信任來源資料 |
實際範例對比
🧩 實際範例:{!! !!} 與 {{ }} 的差別
假設你的 $message 內容是這樣:
<div class="alert">後台管理員輸入的代碼內容</div>
使用一般語法:
{{ $message }}
會輸出:
<div class="alert">後台管理員輸入的代碼內容</div>
這樣畫面上只會看到純文字。
但若改成:
{!! $message !!}
就會正常顯示:
<div class="alert" style="padding:10px;background:#f4f4f4;border-radius:8px;"> 後台管理員輸入的代碼內容 </div>
網站後台欄位實務應用
🧰 實務應用場景:後台自訂區塊的輸出
在實務上,我們通常會遇到這樣的情境:
PHP(Controller)
$data['custom_block'] = $request->input('custom_block');
return view('admin.page', $data);
HTML(Blade)
<section>
{!! $custom_block !!}
</section>
這樣管理者在後台欄位中填入:
<p style="color:red;">🔥 這是後台自訂段落</p>
前端就會原樣呈現,不被 Laravel 轉義。
🧡 重點說明
這個做法最常見於 CMS、行銷頁面、表單頁自訂代碼區、或是插入 GA / Meta 追蹤碼 的欄位。
對於需要高自由度的管理後台而言,這是幾乎不可或缺的輸出方式。
👉 如果你還不熟悉 SEO 的最基本概念,可以先看這篇《什麼是 SEO?別以為網站做完就好,排名關鍵在這裡》。
安全考量:何時該用、何時絕對不能用

{!! $message !!} 雖然能解決「HTML 被吃掉」的問題,但它也同時關掉了 Laravel 的安全防護機制。
換句話說,如果輸入內容來自不可信來源(例如前台使用者),這行語法就可能變成攻擊入口。
🚨 什麼情況「不能用」 {!! !!}
-
前台使用者輸入(留言 / 表單 / 評論)
→ 絕對不要直接輸出!這類內容最容易被夾帶<script>或<iframe>攻擊;若用{!! !!},攻擊者可直接在你站上執行惡意程式。 -
未驗證的 JSON 或外部 API 回傳
→ 有些 API 會回傳含 HTML 的描述欄位,必須先 驗證/轉義或淨化 再輸出,避免把外部 HTML 當成可信內容。 -
模板可編輯欄位(WYSIWYG 編輯器)
→ CKEditor、TinyMCE、Summernote 等輸出的內容應搭配 HTML Sanitizer(例如 HTMLPurifier 或 DOMPurify)過濾危險標籤/屬性,將允許的標籤白名單化。
建議做法:對「來源不可信」的欄位一律使用 {{ }}(轉義)輸出;若確實需要允許部份 HTML,先在後端執行白名單式的 HTML Sanitization,或由後台流程判定後再以 {!! !!} 有條件放行。
{!! !!} 並不是危險,而是強大。
只要清楚知道「內容來源」與「輸出場景」,再搭配適當防護機制,
它就是讓 Laravel 網頁具備靈活內容控制的關鍵工具。
💬 總之太棒了,真開心能成功輸出代碼!
你在開發 Laravel 後台欄位時,是否也曾遇過 HTML 被吃掉、或 特殊符號亂掉 的情況?
妳有其他問題或經驗想分享嗎?歡迎留言告訴我,
我很樂意一起討論更乾淨、安全又靈活的輸出做法。






