Sapper.js - Предварительная загрузка файлов cookie / заголовков?

Я использую Sapper.js для питания своего приложения, но использую только статический контент, созданный при запуске sapper export. Таким образом, сервер не отображает страницы.

Я использую AWS CloudFront с Lambda @ Edge для аутентификации HttpOnly файлов cookie пользователя всякий раз, когда они запрашивают страницу. Если пользователь аутентифицирован, Lambda затем получит данные пользователя, такие как изображение профиля пользователя, имя пользователя и т. Д., И установит эти значения в пользовательских заголовках / файлах cookie (не HttpOnly) на страницах, возвращаемых CloudFront.

Эти значения могут быть установлены либо в заголовках, либо в файлах cookie, для них нет никаких требований.

Но мне нужно, чтобы этот динамический контент был доступен клиенту до того, как страница будет отрисована, чтобы избежать некрасивой вспышки пустого контента. Поэтому его следует извлекать внутри функции sapper preload вместо onMount, чтобы предотвратить рендеринг любого другого HTML до тех пор, пока данные не будут возвращены.

Я знаю, как получить внутри функции preload вот так:

<script context="module">
    export async function preload(page, session) {
        const res = await this.fetch("SOME_ENDPOINT");
        const data = await res.json();

        return {data};
    }
</script>

но я не уверен, как получить доступ к заголовкам или файлам cookie из этой функции.

РЕДАКТИРОВАТЬ: НОВЫЙ ПОДХОД?

Итак, я подумал, и мне кажется, что лучший способ на этом этапе - это попытаться преобразовать функцию sapper.middleware Саппера, чтобы она принимала настраиваемый объект req и возвращала объект res вместо того, чтобы пытаться передать его клиенту.

Затем мы можем запустить npm run build и использовать весь каталог build внутри Lambda. Впоследствии мы можем передавать любые пользовательские данные в объект промежуточного программного обеспечения session, как это объясняется в документации:

sapper.middleware({session: (CUSTOM_REQ, CUSTOM_RES) => ({user: CUSTOME_REQ.user})})

Нет необходимости получать какие-либо данные, поскольку теперь они должны быть доступны в store.

Есть предположения?


person mrstack999    schedule 29.11.2019    source источник
comment
У меня та же проблема   -  person Yousuf Iqbal Hashim    schedule 30.11.2019
comment
Я чувствую тебя. Прочтите мою правку и дайте мне знать, если у вас есть идеи по поводу моего нового подхода   -  person mrstack999    schedule 30.11.2019


Ответы (1)


Вы можете передать { credentials: true } в качестве второго параметра this.fetch (так же, как обычный fetch):

export async function preload(page, session) {
    const res = await this.fetch("SOME_ENDPOINT", {
        credentials: true
    });
    const data = await res.json();

    return {data};
}

Это приведет к отправке файлов cookie с запросом. Однако по определению это не будет работать с экспортированными приложениями - ответ должен быть создан для каждого пользователя.

person Rich Harris    schedule 30.11.2019
comment
В моем случае это не работает, потому что файлы cookie не отправляются клиентом, а устанавливаются Lambda @ Edge и принимаются клиентом. Процесс выглядит следующим образом: Пользователь - ›ПОЛУЧИТЬ конечную точку CloudFront (с любыми файлами cookie, сохраненными браузером) -› CloudFront возвращает html-страницу, на которой находится приложение - ›Lambda @ Edge вводит заголовки / файлы cookie в зависимости от аутентификации -› HTML-страница и заголовки, возвращаемые пользователю. Таким образом, эти значения возвращаются еще до загрузки страницы. Я мог бы пропустить функцию Lambda и вызвать API аутентификации с помощью метода выше, но это вызовет задержку и предоставит дополнительный HTTP-запрос. - person mrstack999; 30.11.2019
comment
{ credentials: 'same-origin' } или { credentials: 'include' } работает в моем случае, я думаю, { credentials: true } для require('cors') или что-то в этом роде - person MaxCore; 09.07.2020