Lewati ke konten

Wadah cookie

Secara bawaan, Phasis milik fetch() mengabaikan Set-Cookie dari respons dan tidak mengirim header Cookie pada permintaan. Ini pilihan bawaan yang tepat untuk penyematan sisi server — biasanya respons seorang pengguna tidak seharusnya memengaruhi permintaan pengguna lain.

Jika Anda memerlukan cookie — untuk alur yang bergantung pada status sesi, scraping di balik login, atau meniru perilaku browser dalam pengujian — pasang wadah dengan $engine->setCookieJar($jar).

Antarmuka

Wadah ini dapat berupa objek apa pun yang menyediakan dua metode:

Kode
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

Objek PHP maupun JS-side JsObject dengan member yang sesuai dapat digunakan. Mengirim null akan mengosongkan wadah.

Phasis memanggil get(url) sekali untuk setiap lompatan permintaan (sehingga pengalihan ke host lain mendapatkan cookie baru) dan set(url, line) sekali untuk setiap header Set-Cookie dalam respons. Kebijakan cookie — pencocokan domain, cakupan path, masa berlaku, SameSite, Secure — menjadi tanggung jawab wadah, bukan Phasis.

Wadah dalam memori (pengujian)

PHP
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());

Ini cukup untuk fixture pengujian jalur normal, tetapi mengabaikan Domain=, Path=, Expires=, dan atribut Secure/HttpOnly/SameSite. Jangan gunakan untuk sesuatu yang melintasi batas kepercayaan.

Symfony BrowserKit

Jika pustaka HTTP milik Symfony sudah terpasang, BrowserKit\CookieJar menangani kebijakan dengan benar.

PHP
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()));

Wadah sisi JS

Jika wadah Anda berada di sisi JS — misalnya karena Anda ingin memeriksa atau mengisinya dari JavaScript — ikat melalui objek JS:

JavaScript
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());
};
PHP
$engine->eval($script);
$engine->setCookieJar($engine->eval('$jar'));

Metode get/set yang sama dipanggil, baik penerimanya objek PHP maupun JsObject.

Cakupan per permintaan

Wadah berada pada realm — wadah ini bertahan di semua fetch() hingga dihapus dengan setCookieJar(null). Untuk membatasi wadah pada satu alur permintaan, lakukan secara eksplisit:

PHP
$engine->setCookieJar($jar);
$engine->eval('await runLoginFlow()');
$engine->setCookieJar(null);

Memeriksa dari PHP

$engine->getCookieJar() mengembalikan apa pun yang diteruskan kepadanya — berguna untuk assertion dalam pengujian.

PHP
$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/'));

Lihat juga

  • Transportasi fetch — wadah cookie berjalan di dalam loop pengalihan milik Phasis, di atas transportasi apa pun yang Anda pasang.
  • API Web (WPT) — pengujian Fetch Pack yang mencakup perilaku cookie.