Cookie-lagring
Som standard ignorerar Phasiss fetch() Set-Cookie från svar och skickar ingen Cookie-header med förfrågningar. Det är rätt standardinställning för inbäddning på serversidan — vanligtvis vill du inte att en användares svar ska påverka en annan användares förfrågan.
Om du behöver cookies — för att köra ett flöde som bygger på sessionstillstånd, skrapa bakom en inloggning eller efterlikna webbläsarens beteende i tester — kopplar du in en lagring med $engine->setCookieJar($jar).
Gränssnittet
Lagringen kan vara vilket objekt som helst som tillhandahåller två metoder:
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
Både PHP-objekt och JS-sidans JsObject med matchande medlemmar fungerar. Om du skickar null rensas lagringen.
Phasis anropar get(url) en gång per omdirigeringssteg (så omdirigeringar till en annan värd får nya cookies) och set(url, line) en gång för varje Set-Cookie-header i svaret. Lagringen ansvarar för cookieprinciper — domänmatchning, sökvägsavgränsning, giltighetstid, SameSite, Secure — inte Phasis.
Lagring i minnet (tester)
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());
Det här räcker för ett testexempel där allt går som det ska, men ignorerar Domain=, Path=, Expires= och attributen Secure/HttpOnly/SameSite. Använd det inte över en förtroendegräns.
Symfony BrowserKit
Om du redan har Symfonys HTTP-bibliotek installerade hanterar BrowserKit\CookieJar principerna korrekt.
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()));
Lagring på JS-sidan
Om din lagring finns på JS-sidan — till exempel för att du vill granska eller fylla den från JavaScript — kopplar du in den via ett JS-objekt:
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'));
Samma metoder get/set anropas oavsett om mottagaren är ett PHP-objekt eller en JsObject.
Omfattning per förfrågan
En lagring finns i miljön — den finns kvar mellan varje fetch() tills den rensas med setCookieJar(null). Om du vill begränsa lagringen till ett enda förfrågningsflöde gör du det uttryckligen:
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
Granska från PHP
$engine->getCookieJar() returnerar det som skickades in — användbart för kontroller i tester.
$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/'));
Se även
- Fetch-transport — cookielagringen körs inuti Phasiss omdirigeringsloop, ovanpå den transport du har installerat.
- Web APIs (WPT) — Fetch Pack-testerna som täcker cookiehantering.