Sīkfailu krātuve
Pēc noklusējuma Phasis fetch() ignorē atbildēs saņemtos Set-Cookie un pieprasījumos nesūta Cookie galveni. Tā ir pareizā noklusējuma izvēle servera puses iegulšanai — parasti nav vēlams, lai viena lietotāja atbilde ietekmētu cita lietotāja pieprasījumu.
Ja sīkfaili ir vajadzīgi — piemēram, plūsmai, kuras darbība ir atkarīga no sesijas stāvokļa, datu ieguvei pēc pieteikšanās vai pārlūka darbības atdarināšanai testos — pievienojiet krātuvi ar $engine->setCookieJar($jar).
Saskarne
Krātuve var būt jebkurš objekts, kas nodrošina divas metodes:
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
Der gan PHP objekti, gan JS puses JsObject objekti ar atbilstošiem dalībniekiem. Nododot null, krātuve tiek notīrīta.
Phasis izsauc get(url) katrā pieprasījuma posmā (tāpēc, novirzot uz citu resursdatoru, tiek iegūti jauni sīkfaili) un set(url, line) katrai Set-Cookie galvenei atbildē. Sīkfailu politika — domēna atbilstība, ceļa tvērums, derīguma termiņš, SameSite, Secure — ir krātuves, nevis Phasis atbildība.
Atmiņas krātuve (testiem)
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());
Ar šo pietiek vienkāršam testu scenārijam, taču tas ignorē Domain=, Path=, Expires= un atribūtus Secure/HttpOnly/SameSite. Neizmantojiet to, šķērsojot uzticamības robežu.
Symfony BrowserKit
Ja jums jau ir instalētas Symfony HTTP bibliotēkas, BrowserKit\CookieJar pareizi pārvalda politiku.
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 puses krātuve
Ja krātuve atrodas JS pusē — piemēram, ja vēlaties to pārbaudīt vai aizpildīt no JavaScript — sasaistiet to ar JS objektu:
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'));
Tās pašas get/set metodes tiek izsauktas neatkarīgi no tā, vai saņēmējs ir PHP objekts vai JsObject.
Tvērums katram pieprasījumam
Krātuve ir piesaistīta realm — tā tiek saglabāta starp visiem fetch(), līdz tiek notīrīta ar setCookieJar(null). Lai krātuves tvērumu ierobežotu līdz vienai pieprasījumu plūsmai, rīkojieties šādi:
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);
Pārbaude no PHP puses
$engine->getCookieJar() atgriež visu, kas tam tika nodots, un tas ir noderīgi apgalvojumu pārbaudēm testos.
$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/'));
Skatiet arī
- Fetch transport — sīkfailu krātuve darbojas Phasis novirzīšanas ciklā, izmantojot jūsu instalēto transportu.
- Tīmekļa API (WPT) — Fetch Pack testi, kas pārbauda sīkfailu darbību.