使用伺服器端包含 (SSI)
與 ESI (邊緣端包含) 類似,SSI 可用於控制回應片段的 HTTP 快取。最重要的區別是,SSI 可被大多數網路伺服器直接識別,例如 Apache、Nginx 等。
SSI 指令透過 HTML 註解完成
1 2 3 4 5 6 7 8 9 10 11
<!DOCTYPE html>
<html>
<body>
<!-- ... some content -->
<!-- Embed the content of another page here -->
<!--#include virtual="/..." -->
<!-- ... more content -->
</body>
</html>
還有其他可用的指令,但 Symfony 僅管理 #include virtual
指令。
危險
使用 SSI 請務必小心,您的網站可能成為注入攻擊的受害者。請先閱讀這篇 OWASP 文章!
當網路伺服器讀取到 SSI 指令時,它會請求給定的 URI 或直接從其快取中取得。它會重複此過程,直到沒有更多 SSI 指令需要處理。然後,它會將所有回應合併為一個並發送給用戶端。
在 Symfony 中使用 SSI
首先,要使用 SSI,請務必在您的應用程式設定中啟用它
1 2 3
# config/packages/framework.yaml
framework:
ssi: { enabled: true }
假設您有一個包含私有內容的頁面,例如個人資料頁面,並且您想要快取靜態 GDPR 內容區塊。透過 SSI,您可以為此區塊新增一些過期時間,並保持頁面的私有性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Controller/ProfileController.php
namespace App\Controller;
use Symfony\Component\HttpKernel\Attribute\Cache;
// ...
class ProfileController extends AbstractController
{
public function index(): Response
{
// by default, responses are private
return $this->render('profile/index.html.twig');
}
#[Cache(smaxage: 600)]
public function gdpr(): Response
{
return $this->render('profile/gdpr.html.twig');
}
}
個人資料索引頁面沒有公開快取,但 GDPR 區塊有 10 分鐘的過期時間。讓我們將此區塊包含到主頁面中
1 2 3 4 5 6 7
{# templates/profile/index.html.twig #}
{# you can use a controller reference #}
{{ render_ssi(controller('App\\Controller\\ProfileController::gdpr')) }}
{# ... or a path (in server's SSI configuration is common to use relative paths instead of absolute URLs) #}
{{ render_ssi(path('profile_gdpr')) }}
render_ssi
twig helper 會產生類似以下的內容
1
<!--#include virtual="/_fragment?_hash=abcdef1234&_path=_controller=App\Controller\ProfileController::gdpr" -->
render_ssi
確保僅當請求具有標頭需求(例如 Surrogate-Capability: device="SSI/1.0"
,通常由網路伺服器提供)時,才會產生 SSI 指令。否則,它將直接嵌入子回應。
注意
有關 Symfony 快取片段的更多資訊,請參閱 ESI 文件。
本作品(包括程式碼範例)採用 Creative Commons BY-SA 3.0 授權條款。