Úložisko súborov cookie
Predvolené fetch() v Phasis ignoruje Set-Cookie z odpovedí a v požiadavkách neposiela hlavičku Cookie. Pre vkladanie na strane servera je to správne predvolené správanie — zvyčajne nechcete, aby odpoveď jedného používateľa ovplyvnila požiadavku iného.
Ak súbory cookie potrebujete — napríklad pri vykonávaní postupu závislého od stavu relácie, prehliadaní stránok za prihlásením alebo napodobňovaní správania prehliadača v testoch — pripojte úložisko pomocou $engine->setCookieJar($jar).
Rozhranie
Úložiskom môže byť ľubovoľný objekt, ktorý podporuje dve metódy:
get(url: string): string // returns a "Cookie:" header value, e.g. "sid=abc; pref=dark"
set(url: string, header: string): void // receives one Set-Cookie line
Fungujú objekty PHP aj JS-stranové JsObject so zodpovedajúcimi členmi. Odovzdaním null úložisko vymažete.
Phasis volá get(url) raz pre každý krok požiadavky (presmerovania na iný hostiteľ tak dostanú nové súbory cookie) a set(url, line) raz pre každú hlavičku Set-Cookie v odpovedi. Za politiku súborov cookie — zhodu domény, rozsah cesty, platnosť, SameSite, Secure — zodpovedá úložisko, nie Phasis.
Úložisko v pamäti (testy)
final class MemoryJar
{
/** @var array<string, array<string, string>> host → name → "name=value" */
private array $store = [];
public function get(string $url): string
{
$host = parse_url($url, PHP_URL_HOST) ?? '';
return implode('; ', $this->store[$host] ?? []);
}
public function set(string $url, string $header): void
{
$host = parse_url($url, PHP_URL_HOST) ?? '';
[$nv] = explode(';', $header, 2);
[$name, $value] = explode('=', trim($nv), 2) + ['', ''];
if ($name !== '') {
$this->store[$host][$name] = "$name=$value";
}
}
}
$engine->setCookieJar(new MemoryJar());
Toto stačí ako testovacia pomôcka pre úspešný prípad, ignoruje však Domain=, Path=, Expires= aj atribúty Secure/HttpOnly/SameSite. Nepoužívajte ho tam, kde sa prekračuje hranica dôvery.
Symfony BrowserKit
Ak už máte nainštalované knižnice HTTP pre Symfony, BrowserKit\CookieJar spravuje politiku správne.
use Symfony\Component\BrowserKit\CookieJar as BrowserCookieJar;
use Symfony\Component\BrowserKit\Cookie;
final class SymfonyJarAdapter
{
public function __construct(private BrowserCookieJar $jar) {}
public function get(string $url): string
{
$cookies = $this->jar->allValues($url);
return implode('; ', array_map(
fn ($n, $v) => "$n=$v",
array_keys($cookies),
array_values($cookies),
));
}
public function set(string $url, string $header): void
{
$cookie = Cookie::fromString($header, $url);
$this->jar->set($cookie);
}
}
$engine->setCookieJar(new SymfonyJarAdapter(new BrowserCookieJar()));
Úložisko na strane JS
Ak sa vaše úložisko nachádza na strane JS — napríklad ak ho chcete prezerať alebo naplniť údajmi z JavaScript — pripojte ho cez objekt JS:
const jar = new Map();
$jar.get = (url) => Array.from(jar.entries()).map(([k, v]) => `${k}=${v}`).join('; ');
$jar.set = (url, header) => {
const [nv] = header.split(';');
const [name, value] = nv.split('=');
jar.set(name.trim(), value.trim());
};
$engine->eval($script);
$engine->setCookieJar($engine->eval('$jar'));
Volajú sa rovnaké metódy get/set bez ohľadu na to, či je prijímateľom objekt PHP alebo JsObject.
Rozsah jednej požiadavky
Úložisko patrí do kontextu — pretrváva vo všetkých požiadavkách fetch() až do vymazania pomocou setCookieJar(null). Ak chcete obmedziť jeho platnosť na jeden tok požiadaviek, urobte to výslovne:
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
Kontrola z PHP
$engine->getCookieJar() vráti odovzdanú hodnotu — užitočné pri overovaní v testoch.
$jar = new MemoryJar();
$engine->setCookieJar($jar);
$engine->eval('await fetch("https://api.example.com/login", { method: "POST" })');
assertNotEmpty($engine->getCookieJar()->get('https://api.example.com/'));
Pozrite si aj
- Transport fetch — úložisko súborov cookie beží vnútri slučky presmerovaní Phasis a je navrstvené na nainštalovaný transport.
- Webové API (WPT) — testy Fetch Pack pokrývajúce správanie súborov cookie.