Cookie-lager
Som standard ignorerer Phasiss fetch() Set-Cookie fra svar og sender ingen Cookie-header med anmodninger. Det er den rette standardindstilling til indlejring på serversiden — typisk ønsker du ikke, at én brugers svar påvirker en anden brugers anmodning.
Hvis du har brug for cookies — til et forløb, der afhænger af sessionstilstand, scraping efter login eller til at efterligne en browsers adfærd i tests — kan du tilføje et lager med $engine->setCookieJar($jar).
Grænsefladen
Lageret kan være et hvilket som helst objekt, der har to 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-objekter og JS-JsObjects med de samme medlemmer virker. Sender du null, tømmes lageret.
Phasis kalder get(url) én gang for hvert anmodningshop (så omdirigeringer til en anden vært får friske cookies) og set(url, line) én gang for hver Set-Cookie-header i svaret. Cookiepolitik — domænematchning, afgrænsning efter sti, udløb, SameSite, Secure — håndteres af lageret, ikke af Phasis.
Lager i hukommelsen (tests)
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 er nok til en testfixture af happy-path-typen, men ignorerer Domain=, Path=, Expires= og attributterne Secure/HttpOnly/SameSite. Brug det ikke til noget, der krydser en tillidsgrænse.
Symfony BrowserKit
Hvis du allerede har Symfonys HTTP-biblioteker installeret, håndterer BrowserKit\CookieJar politikken 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()));
JS-lager på serversiden
Hvis din cookiebeholder ligger på JS-siden — for eksempel fordi du vil inspicere eller fylde den fra JavaScript — skal du tilknytte den via et 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'));
De samme metoder get/set kaldes, uanset om modtageren er et PHP-objekt eller en JsObject.
Omfang pr. anmodning
Et lager tilhører realm'et — det bevares på tværs af alle fetch(), indtil det tømmes med setCookieJar(null). Vil du begrænse et lager til ét anmodningsforløb, skal du gøre det eksplicit:
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
Inspektion fra PHP
$engine->getCookieJar() returnerer det, der blev sendt ind — nyttigt til assertions i tests.
$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 også
- Fetch-transport — cookie-lageret kører inde i Phasiss omdirigeringsløkke og føjes til den transport, du har installeret.
- Web-API'er (WPT) — Fetch Pack-testene, der dækker cookieadfærd.