Recipient de cookie-uri
În mod implicit, Phasis's fetch() ignoră Set-Cookie din răspunsuri și nu trimite antetul Cookie în cereri. Acesta este comportamentul implicit potrivit pentru încorporarea pe server — de obicei nu doriți ca răspunsul unui utilizator să influențeze cererea altuia.
Dacă doriți cookie-uri — pentru a parcurge un flux care depinde de starea sesiunii, a extrage date după autentificare sau a reproduce comportamentul unui browser în teste — atașați un recipient prin $engine->setCookieJar($jar).
Interfața
Recipientul este orice obiect care implementează două metode:
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
Funcționează atât obiectele PHP, cât și JS-side JsObject cu membri corespunzători. Transmiterea lui null golește recipientul.
Phasis apelează get(url) o dată pentru fiecare etapă a cererii (astfel, redirecționările către altă gazdă primesc cookie-uri noi) și set(url, line) o dată pentru fiecare antet Set-Cookie din răspuns. Politica cookie-urilor — potrivirea domeniului, restricționarea căii, expirarea, SameSite, Secure — ține de recipient, nu de Phasis.
Recipient în memorie (teste)
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());
Este suficient pentru un scenariu de testare de bază, dar ignoră Domain=, Path=, Expires= și atributele Secure/HttpOnly/SameSite. Nu îl folosiți pentru nimic care traversează o limită de încredere.
Symfony BrowserKit
Dacă aveți deja instalate bibliotecile HTTP ale Symfony, BrowserKit\CookieJar gestionează corect politica.
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()));
Recipient pentru JS
Dacă recipientul se află în JS — de exemplu, pentru că doriți să îl inspectați sau să îl inițializați din JavaScript — conectați-l printr-un obiect 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'));
Se apelează aceleași metode get/set, indiferent dacă receptorul este un obiect PHP sau un JsObject.
Domeniu de aplicare per cerere
Un recipient aparține mediului de execuție — persistă pe durata fiecărei fetch() până când este golit cu setCookieJar(null). Pentru a limita un recipient la un singur flux de cereri, faceți acest lucru explicit:
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
Inspectarea din PHP
$engine->getCookieJar() returnează valoarea transmisă — utilă pentru aserțiuni în teste.
$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/'));
Consultați și
- Transportul fetch — recipientul de cookie-uri rulează în interiorul buclei de redirecționare a Phasis, peste transportul instalat.
- API-uri web (WPT) — testele Fetch Pack care acoperă comportamentul cookie-urilor.