跳到主要內容

使用伺服器端包含 (SSI)

編輯此頁面

ESI (邊緣端包含) 類似,SSI 可用於控制回應片段的 HTTP 快取。最重要的區別是,SSI 可被大多數網路伺服器直接識別,例如 ApacheNginx 等。

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 授權條款。
目錄
    版本