HTTP response
Nette zapouzdřuje HTTP odpověď do objektů se srozumitelným API.
HTTP odpověď představuje objekt Nette\Http\Response. Pokud pracujete s Nette, tento objekt
je automaticky vytvořen frameworkem a můžete si jej nechat předat pomocí dependency injection. V presenterech stačí jen
zavolat metodu $this->getHttpResponse().
Nette\Http\Response
Objekt je na rozdíl od Nette\Http\Request mutable, tedy pomocí setterů
můžete měnit stav, tedy např. odesílat hlavičky. Nezapomeňte, že všechny settery musí být volány před odesláním
jakéhokoli výstupu. Jestli už byl výstup odeslán prozradí metoda isSent(). Pokud vrací true,
každý pokus o odeslání hlavičky vyvolá výjimku Nette\InvalidStateException.
setCode (int $code, ?string $reason=null)
Změní stavový kód odpovědi. Kvůli lepší srozumitelnosti zdrojového kódu doporučujeme pro kód používat místo čísel předdefinované konstanty.
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
getCode(): int
Vrací stavový kód odpovědi.
isSent(): bool
Vrací, zda už došlo k odeslání hlaviček ze serveru do prohlížeče, a tedy již není možné odesílat hlavičky či měnit stavový kód.
setHeader (string $name, ?string $value)
Odešle HTTP hlavičku a přepíše dříve odeslanou hlavičku stejného jména. Pokud je $value
null, bude hlavička odstraněna.
$httpResponse->setHeader('Pragma', 'no-cache');
addHeader (string $name, string $value)
Odešle HTTP hlavičku a nepřepíše dříve odeslanou hlavičku stejného jména.
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
deleteHeader (string $name)
Smaže dříve odeslanou HTTP hlavičku.
getHeader (string $header): ?string
Vrací odeslanou HTTP hlavičku nebo null, pokud taková neexistuje. Parametr je case-insensitive.
$pragma = $httpResponse->getHeader('Pragma');
getHeaders(): array<string, string>
Vrací všechny odeslané HTTP hlavičky jako asociativní pole.
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
setContentType (string $type, ?string $charset=null)
Mění hlavičku Content-Type.
$httpResponse->setContentType('text/plain', 'UTF-8');
redirect (string $url, int $code=self::S302_Found): void
Přesměruje na jiné URL. Nezapomeňte poté ukončit skript.
$httpResponse->redirect('http://example.com');
exit;
setExpiration (?string $expire)
Nastaví expiraci HTTP dokumentu pomocí hlaviček Cache-Control a Expires. Parametrem je buď
časový interval (jako text), nebo null, což zakáže kešování.
// cache v prohlížeči vyprší za hodinu
$httpResponse->setExpiration('1 hour');
sendAsFile (string $fileName)
Odpověď bude stažena pomocí dialogového okna Uložit jako pod uvedeným názvem. Samotný soubor přitom neodesílá.
$httpResponse->sendAsFile('faktura.pdf');
setCookie (string $name, string $value,
$expire, ?string $path=null, ?string $domain=null, ?bool $secure=null, ?bool $httpOnly=null,
SameSite|string $sameSite='Lax', bool $partitioned=false)
Odešle cookie. Výchozí hodnoty parametrů:
$path |
'/' |
cookie má dosah na všechny cesty v (sub)doméně (konfigurovatelné) |
$domain |
null |
což znamená s dosahem na aktuální (sub)doménu, ale nikoliv její subdomény (konfigurovatelné) |
$secure |
auto |
true, pokud web běží na HTTPS, jinak false (výchozí nastavení frameworku; samotná třída má
výchozí false) (konfigurovatelné) |
$httpOnly |
true |
cookie je pro JavaScript nepřístupná |
$sameSite |
'Lax' |
cookie nemusí být odeslána při přístupu z jiné domény |
$partitioned |
false |
zda je cookie partitioned, viz níže (od verze 3.4) |
Výchozí hodnoty parametrů $path, $domain a $secure můžete změnit v konfiguraci.
Expiraci lze uvést jako počet sekund, jako textový interval nebo datum, případně jako objekt
DateTimeInterface. Hodnota null vytvoří session cookie, kterou prohlížeč zahodí při svém
zavření. Nette expiraci odesílá v atributu Expires i Max-Age.
$httpResponse->setCookie('lang', 'cs', '100 days'); // vyprší za 100 dní
$httpResponse->setCookie('lang', 'cs', null); // session cookie
Parametr $domain určuje, které domény mohou cookie přijímat. Není-li uveden, cookie přijímá stejná
(sub)doména, jako ji nastavila, ale nikoliv její subdomény. Pokud je $domain zadaný, jsou zahrnuty i subdomény.
Proto je uvedení $domain méně omezující než vynechání. Například při $domain = 'nette.org'
jsou cookies dostupné i na všech subdoménách jako doc.nette.org.
Hodnotu $sameSite můžete předat jako enum Nette\Http\SameSite – SameSite::Lax,
SameSite::Strict nebo SameSite::None (fungují i řetězce 'Lax', 'Strict',
'None'). Pokud ji nastavíte na SameSite::None, automaticky se zapne atribut $secure,
protože prohlížeče cookie se SameSite=None bez něj odmítají.
Partitioned cookies (CHIPS) dávají cookie samostatné úložiště pro každý web nejvyšší úrovně.
Když tedy služba třetí strany (například vložený widget) nastaví partitioned cookie, prohlížeč pro každý web, na
kterém se widget objeví, uchovává oddělenou kopii a tyto kopie nelze vzájemně propojit pro sledování napříč weby.
Zapnete je nastavením $partitioned na true; to zároveň vyžaduje atribut $secure, takže
se zapne automaticky.
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
deleteCookie (string $name, ?string $path=null, ?string $domain=null, ?bool $secure=null): void
Smaže cookie. Výchozí hodnoty parametrů jsou:
$paths dosahem na všechny adresáře ('/')$domains dosahem na aktuální (sub)doménu, ale nikoliv její subdomény$securese řídí podle nastavení v konfiguraci
$httpResponse->deleteCookie('lang');
Nette\Http\Context
Objekt Nette\Http\Context spojuje dohromady požadavek a odpověď a pomáhá s HTTP kešováním. Není registrován jako služba, vytvoříte si jej sami. V presenterech je obvykle pohodlnější použít metodu lastModified(), context se hodí ve chvíli, kdy odpověď odesíláte sami, například z vlastní třídy response.
isModified (string|int|\DateTimeInterface|null $lastModified=null, ?string $etag=null): bool
Zjišťuje, zda se obsah od poslední návštěvy klienta změnil. Pokud předáte čas poslední změny, odešle hlavičku
Last-Modified, pokud předáte ETag validátor (krátký řetězec identifikující aktuální verzi obsahu,
například jeho hash), odešle hlavičku ETag. Obojí pak porovná s hlavičkami If-Modified-Since a
If-None-Match, které poslal prohlížeč.
Pokud už prohlížeč aktuální verzi má, metoda nastaví kód 304 Not Modified a vrátí
false – v takovém případě tělo odpovědi vůbec neodesílejte. V opačném případě vrátí
true.
public function send(Nette\Http\IRequest $request, Nette\Http\IResponse $response): void
{
$context = new Nette\Http\Context($request, $response);
if ($context->isModified(filemtime($this->file), md5_file($this->file))) {
readfile($this->file);
}
}
Oba parametry jsou volitelné. Pokud čas změny obsahu neznáte, použijte jen ETag, a naopak.