O que acontece aos URLs localhost na pré-visualização de um desafio de código
O código do browser que chama http://localhost:4000 é enviado para a porta 4000 da sandbox, com CORS, redirecionamentos e cookies tratados. Para os poucos casos que não alcança, usa um caminho relativo ou routing.<service>.url.
O frontend de um projeto chama muitas vezes a sua API em http://localhost:4000, a partir de um ficheiro de ambiente como
NEXT_PUBLIC_API_URL ou escrito diretamente no código. Numa pré-visualização do Kendor, a página corre no
browser de quem a vê, onde localhost é o computador dessa pessoa e não a sandbox. O Kendor redireciona essas chamadas para
a porta certa na sandbox, por isso a maioria dos projetos funciona sem alterações. Este artigo explica o que é
redirecionado, o que não é, e a forma explícita de construir URLs quando preferes não depender disso.
O que o Kendor redireciona
Qualquer URL cujo anfitrião seja localhost, 127.0.0.1, 0.0.0.0 ou [::1], em qualquer porta, feito a partir da
página de pré-visualização ou dos seus web workers:
- pedidos com
fetcheXMLHttpRequest(e, portanto, axios e a maioria das outras bibliotecas HTTP) - WebSockets, incluindo socket.io e hot reload, e server-sent events (
EventSource) - imagens, scripts, folhas de estilo, vídeo, iframes, ligações e formulários, quer estejam no HTML servido, definidos a partir de JavaScript, ou inseridos como markup
- redirecionamentos do teu servidor para
http://localhost:…
Não importa de onde vem o URL: uma variável de ambiente incluída no bundle, um texto escrito diretamente no código, ou um construído em tempo de execução.
Para onde vai um URL redirecionado
- Se o
routingdo desafio enviar esse caminho para essa porta, o URL vai para o próprio endereço da pré-visualização. Por exemplo,http://localhost:4000/api/usersvai parahttps://<preview-address>/api/usersquando/apiencaminha para o serviço na porta 4000. O frontend e a API partilham então um único endereço, por isso não há CORS nenhum. - Caso contrário, vai para o endereço próprio dessa porta,
https://4000-<preview-address>/api/users, o mesmo endereço que a vista Processos abre para essa porta.
A primeira vez que uma porta é redirecionada, a consola do browser avisa:
[kendor] localhost:4000 is the sandbox's port 4000 here, reached at https://4000-<preview-address>.
CORS, redirecionamentos e cookies
Uma chamada da pré-visualização para o endereço de outra porta é entre origens diferentes, por isso o Kendor faz com que ela se pareça com o que era na tua máquina:
- CORS. A tua API recebe
Origin: http://localhost:3000(a porta de onde a página veio), por isso uma lista de permissões escrita para desenvolvimento local passa. A resposta é mapeada de volta para o endereço da pré-visualização. Só as chamadas da pré-visualização do próprio desafio recebem este tratamento; os pedidos de qualquer outro site ficam como estão. - Redirecionamentos. Um cabeçalho
Location: http://localhost:3000/dashboardé reescrito para o endereço da pré-visualização. - Cookies. A pré-visualização aparece dentro do editor, noutro site, onde os browsers descartam os cookies
normais. O Kendor marca os cookies da tua app como particionados (
SameSite=None; Secure; Partitioned), para que um início de sessão com cookie funcione também aí. Um cookie comDomain=localhostfica sem esse domínio.
O código do lado do servidor não precisa de nada disto. Dentro da sandbox, o localhost já chega ao processo
certo, por isso um componente de servidor Next.js ou uma API que chame outro serviço em http://localhost:4000
funciona como na tua máquina.
O que não é redirecionado
- Um
url()de CSS que aponte paralocalhost, comobackground: url(http://localhost:4000/bg.png). - Workers criados a partir de um URL blob ou data, em vez de um ficheiro de script.
- Navegação de página definida em código, como
location.href = 'http://localhost:3000/login', no Firefox. O Chrome, o Edge e o Safari estão cobertos. - URLs de callback OAuth registados num fornecedor como o Google ou o GitHub como
localhost. Atualiza-os no fornecedor, ou inicia sessão com uma conta de teste de outra forma. - Um servidor que escuta apenas em
127.0.0.1. A pré-visualização não o consegue alcançar de todo. Escuta em$HOST(0.0.0.0).
Quando a página ainda carrega algo de localhost, a consola do browser indica qual é o 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.
O Chrome pode também pedir a quem vê permissão para aceder à rede local. As duas coisas significam o mesmo: altera esse URL como descrito abaixo.
A forma explícita
Em vez de dependeres do redirecionamento, podes dar tu mesmo ao browser o endereço certo. De qualquer das formas funciona na sandbox e na tua máquina.
- Um caminho relativo. Com o
routinga enviar/apipara a tua API, chamafetch('/api/users'). O frontend e a API partilham o endereço da pré-visualização. Vê apps com vários serviços. - Uma referência em
dev.env.vars. Define a variável de API do teu frontend com o URL público da API:
services:
web:
dev:
command: npm run dev -- --port $PORT
port: 5173
env:
vars:
VITE_API_URL: routing.api.urlrouting.api.url resolve para o endereço da pré-visualização mais a rota da API, antes de qualquer serviço arrancar.
Todos os comandos dev recebem também KENDOR_PUBLIC_HOST, o nome de anfitrião da pré-visualização, para o código que constrói
URLs por si. O endereço próprio de uma porta é esse anfitrião com <port>- à frente.
Desativar
Se a tua app mapeia os seus próprios URLs e queres que as páginas sejam servidas exatamente como escritas, envia o cabeçalho
x-kendor-no-rewrite nas respostas HTML. O Kendor deixa então essas páginas em paz.