Робота з включеннями серверних сторін (SSI)

Дата оновлення перекладу 2022-12-15

Робота з включеннями серверних сторін (SSI)

SSI можуть бути використані для контролю HTTP-кешування фрагментів відповіді, схоже на с ESI (Edge Side Includes). Найваживішою відмінністю є те, що SSI напряму відомі більшості веб-серверів на кшталт Apache, Nginx та ін.

Інструкції SSI проводяться за допомогою HTML-коментарів:

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
    <body>
        <!-- ... деякий зміст -->

        <!-- Вбудувати зміст іншої сторінки тут -->
        <!--#include virtual="http://..." -->

        <!-- ... більше змісту -->
    </body>
</html>

Існують деякі інші доступні директиви, але Symfony працює лише з #include virtual.

Caution

Будьте обережні з SSI, ваш веб-сайт може стати жертвою впроваджень. Будь ласка, спочатку, прочитайте цю статтю OWASP!

Коли веб-сервер читає SSI-директиву, він запитує заданий URI або дає напряму зі свого кешу. Він повторює цей процес до тих пір, поки SSI-директиви для обробки не закінчуються. Потім, він зливає всі відповіді в одну, і відправляє їх клієнту.

Використання SSI в Symfony

Для початку, щоб використовувати SSI, не забудьте додати його у конфігурацію вашого додатку:

  • YAML
  • XML
  • PHP
1
2
3
# config/packages/framework.yaml
framework:
    ssi: { enabled: true }

Припустимо, що у вас є сторінка з приватним змістом, на кшталт сторінки Профілю, і ви хочете кешувати статичний блок змісту GDPR. З SSI, ви можете додати закінчення строку дії цьому блоку, щоб сторінка залишалась приватною:

  • Attributes
  • PHP
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 #}

{# ви можете використати посилання контролера #}
{{ render_ssi(controller('App\\Controller\\ProfileController::gdpr')) }}

{# ... або шлях (у конфігурації сервера SSI розвпосюджено використання релятивних шляхів замість абсолютних URL) #}
{{ render_ssi(url('profile_gdpr')) }}

Помічник twig render_ssi згенерує щось типу:

1
<!--#include virtual="/_fragment?_hash=abcdef1234&_path=_controller=App\Controller\ProfileController::gdpr" -->

render_ssi гарантує, що SSI-директиви генеруються лише якщо запит має вимогу заголовку на кшталт Surrogate-Capability: device="SSI/1.0" (зазвичай задається веб-сервером). В інших випадках, він вбудує субвідповідь напряму.

Note

Щоб дізнатися більше про фрагмент кешу Symfony, перегляньте документацію ESI .