Что происходит с localhost-адресами в превью задачи по программированию
Код в браузере, который обращается к http://localhost:4000, перенаправляется на порт 4000 в песочнице, а CORS, редиректы и cookie обрабатываются. Для редких случаев, до которых это не дотягивается, используйте относительный путь или routing.<service>.url.
Фронтенд проекта часто обращается к своему API по адресу http://localhost:4000 — из env-файла,
например NEXT_PUBLIC_API_URL, или прямо из кода. В превью Kendor страница работает в браузере
зрителя, где localhost — это его собственный компьютер, а не песочница. Kendor перенаправляет такие
вызовы на нужный порт в песочнице, поэтому большинство проектов работают без правок. В этой статье
разобрано, что перенаправляется, что нет и как явно строить адреса, если не хочется на это
полагаться.
Что перенаправляет Kendor
Любой URL, хост которого localhost, 127.0.0.1, 0.0.0.0 или [::1], на любом порту, если он
вызван со страницы превью или из её веб-воркеров:
- запросы через
fetchиXMLHttpRequest(а значит, и axios, и большинство других HTTP-библиотек) - WebSocket, включая socket.io и горячую перезагрузку, а также server-sent events (
EventSource) - изображения, скрипты, стили, видео, iframe, ссылки и формы — заданные в отдаваемом HTML, из JavaScript или вставленные как разметка
- редиректы вашего сервера на
http://localhost:…
Не важно, откуда взялся URL: из переменной окружения, вшитой в бандл, из строки в коде или собранный во время выполнения.
Куда ведёт перенаправленный URL
- Если
routingзадачи направляет этот путь на этот порт, URL ведёт на сам адрес превью. Например,http://localhost:4000/api/usersпопадает наhttps://<preview-address>/api/users, когда/apiнаправлен на сервис на порту 4000. Фронтенд и API при этом делят один адрес, так что CORS нет вообще. - Иначе URL ведёт на собственный адрес этого порта,
https://4000-<preview-address>/api/users— тот самый адрес, который представление Процессы открывает для этого порта.
При первом перенаправлении порта консоль браузера сообщает об этом:
[kendor] localhost:4000 is the sandbox's port 4000 here, reached at https://4000-<preview-address>.
CORS, редиректы и cookie
Вызов из превью на адрес другого порта — кросс-доменный, поэтому Kendor делает его таким, каким он был на вашей машине:
- CORS. Ваш API получает
Origin: http://localhost:3000(порт, с которого пришла страница), так что список разрешённых источников, написанный для локальной разработки, срабатывает. Ответ отображается обратно на адрес превью. Это действует только для вызовов из собственного превью задачи; запросы с любых других сайтов остаются как есть. - Редиректы. Заголовок
Location: http://localhost:3000/dashboardпереписывается на адрес превью. - Cookie. Превью показывается внутри редактора, то есть на другом сайте, где браузеры отбрасывают
обычные cookie. Kendor помечает cookie вашего приложения как partitioned
(
SameSite=None; Secure; Partitioned), так что вход по cookie работает и там. Из cookie сDomain=localhostэтот домен убирается.
Серверному коду всё это не нужно. Внутри песочницы localhost и так попадает на нужный процесс, так
что серверный компонент Next.js или API, вызывающий другой сервис по http://localhost:4000,
работает так же, как на вашей машине.
Что не перенаправляется
- CSS
url(), указывающий наlocalhost, напримерbackground: url(http://localhost:4000/bg.png). - Воркеры, созданные из blob или data URL, а не из файла скрипта.
- Переход по страницам, заданный в коде, например
location.href = 'http://localhost:3000/login', в Firefox. Chrome, Edge и Safari поддерживаются. - OAuth callback-адреса, зарегистрированные у провайдера вроде Google или GitHub как
localhost. Обновите их у провайдера или войдите с тестовой учётной записью другим способом. - Сервер, слушающий только
127.0.0.1. Превью до него не достучится вообще. Слушайте$HOST(0.0.0.0).
Когда страница всё же загружает что-то с localhost, консоль браузера сообщает, какой именно URL:
[kendor] This page loaded http://localhost:4000/bg.png (css). That address is the viewer's own
computer, not the sandbox, and Kendor couldn't redirect this one.
Chrome может также запросить у зрителя разрешение на доступ к локальной сети. Оба случая означают одно и то же: измените этот URL, как описано ниже.
Явный способ
Вместо того чтобы полагаться на перенаправление, можно самим дать браузеру правильный адрес. Оба способа работают и в песочнице, и на вашей машине.
- Относительный путь. Если
routingнаправляет/apiна ваш API, вызывайтеfetch('/api/users'). Фронтенд и API делят адрес превью. См. приложения из нескольких сервисов. - Ссылка в
dev.env.vars. Задайте переменную API вашего фронтенда равной публичному URL API:
services:
web:
dev:
command: npm run dev -- --port $PORT
port: 5173
env:
vars:
VITE_API_URL: routing.api.urlrouting.api.url превращается в адрес превью плюс маршрут API ещё до запуска любого сервиса.
Каждая dev-команда получает также KENDOR_PUBLIC_HOST — имя хоста превью — для кода, который сам
собирает URL. Собственный адрес порта — это этот хост с префиксом <port>-.
Отключение
Если ваше приложение само сопоставляет свои URL и вы хотите, чтобы его страницы отдавались ровно так,
как написаны, отправляйте в HTML-ответах заголовок x-kendor-no-rewrite. Тогда Kendor не будет
трогать эти страницы.