Odpowiedź HTTP
Nette zamyka odpowiedź HTTP w obiektach o przejrzystym API.
Odpowiedź HTTP reprezentuje obiekt Nette\Http\Response. Jeśli pracujesz z Nette, obiekt ten
tworzy framework automatycznie, a możesz sobie go pozwolić przekazać przez wstrzykiwanie zależności. W presenterach wystarczy
wywołać metodę $this->getHttpResponse().
Nette\Http\Response
W przeciwieństwie do Nette\Http\Request obiekt ten jest zmienny, więc
możesz setterami zmieniać stan, na przykład wysyłać nagłówki. Pamiętaj, że wszystkie settery muszą być wywołane
przed wysłaniem jakiegokolwiek faktycznego wyjścia. To, czy wyjście zostało już wysłane, mówi metoda
isSent(). Jeśli zwraca true, każda próba wysłania nagłówka rzuci
Nette\InvalidStateException.
setCode (int $code, ?string $reason=null)
Zmienia statusowy kod odpowiedzi. Dla lepszej czytelności kodu źródłowego zaleca się używanie zamiast liczb predefiniowanych stałych.
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
getCode(): int
Zwraca kod statusu odpowiedzi.
isSent(): bool
Zwraca informację, czy nagłówki zostały już wysłane z serwera do przeglądarki, czyli czy nie da się już wysyłać nagłówków ani zmieniać kodu statusu.
setHeader (string $name, ?string $value)
Wysyła nagłówek HTTP i nadpisuje wcześniej wysłany nagłówek o tej samej nazwie. Jeśli $value to
null, nagłówek zostanie usunięty.
$httpResponse->setHeader('Pragma', 'no-cache');
addHeader (string $name, string $value)
Wysyła nagłówek HTTP i nie nadpisuje wcześniej wysłanego nagłówka o tej samej nazwie.
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
deleteHeader (string $name)
Usuwa wcześniej wysłany nagłówek HTTP.
getHeader (string $header): ?string
Zwraca wysłany nagłówek HTTP albo null, jeśli nie istnieje. Parametr nie rozróżnia wielkości liter.
$pragma = $httpResponse->getHeader('Pragma');
getHeaders(): array<string, string>
Zwraca wszystkie wysłane nagłówki HTTP jako tablicę asocjacyjną.
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
setContentType (string $type, ?string $charset=null)
Zmienia nagłówek Content-Type.
$httpResponse->setContentType('text/plain', 'UTF-8');
redirect (string $url, int $code=self::S302_Found): void
Przekierowuje na inny URL. Pamiętaj, żeby potem zakończyć skrypt.
$httpResponse->redirect('http://example.com');
exit;
setExpiration (?string $expire)
Ustawia wygaśnięcie dokumentu HTTP za pomocą nagłówków Cache-Control i Expires. Parametrem jest
albo interwał czasowy (jako tekst), albo null, co wyłącza cache.
// cache przeglądarki wygasa za godzinę
$httpResponse->setExpiration('1 hour');
sendAsFile (string $fileName)
Odpowiedź zostanie pobrana przez okno dialogowe Zapisz jako pod podaną nazwą. Samego pliku nie wysyła.
$httpResponse->sendAsFile('invoice.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)
Wysyła cookie. Domyślne wartości parametrów:
$path |
'/' |
cookie jest dostępne dla wszystkich ścieżek w (sub)domenie (konfigurowalne) |
$domain |
null |
czyli dostępne dla bieżącej (sub)domeny, ale nie jej subdomen (konfigurowalne) |
$secure |
auto |
true, jeśli witryna działa na HTTPS, w przeciwnym razie false (domyślnie we frameworku; sama
klasa ma domyślnie false) (konfigurowalne) |
$httpOnly |
true |
cookie jest niedostępne dla JavaScriptu |
$sameSite |
'Lax' |
cookie może nie zostać wysłane przy dostępie cross-origin |
$partitioned |
false |
czy cookie jest partycjonowane, patrz niżej (od v3.4) |
Wartości domyślne parametrów $path, $domain i $secure możesz zmienić w konfiguracji.
Wygaśnięcie przekazuje się jako liczbę sekund, jako tekstowy interwał albo datę, albo jako obiekt
DateTimeInterface. Wartość null tworzy cookie sesyjne, które przeglądarka odrzuca przy zamknięciu.
Nette wysyła wygaśnięcie w atrybutach Expires i Max-Age.
$httpResponse->setCookie('lang', 'en', '100 days'); // wygasa za 100 dni
$httpResponse->setCookie('lang', 'en', null); // cookie sesyjne
Parametr $domain określa, które domeny mogą przyjąć cookie. Jeśli nie zostanie podany, cookie przyjmuje ta
sama (sub)domena, która je ustawiła, ale nie jej subdomeny. Jeśli $domain zostanie podany, subdomeny również są
objęte. Podanie $domain jest więc mniej restrykcyjne niż jego pominięcie. Na przykład przy
$domain = 'nette.org' cookies są dostępne również we wszystkich subdomenach, jak doc.nette.org.
Wartość $sameSite możesz przekazać jako enum Nette\Http\SameSite: SameSite::Lax,
SameSite::Strict albo SameSite::None (wartości tekstowe 'Lax', 'Strict',
'None' też działają). Jeśli ustawisz SameSite::None, atrybut $secure włącza się
automatycznie, bo przeglądarki odrzucają cookie SameSite=None, które nie jest secure.
Cookies partycjonowane (CHIPS) dają cookie własny, osobny magazyn dla każdej witryny najwyższego
poziomu. Gdy więc usługa zewnętrzna (na przykład osadzony widget) ustawi cookie partycjonowane, przeglądarka trzyma osobną
kopię dla każdej witryny, na której widget się pojawia, a kopii tych nie da się ze sobą powiązać na potrzeby śledzenia
międzywitrynowego. Włączysz je, ustawiając $partitioned na true; wymaga to również atrybutu
$secure, więc włącza się on automatycznie.
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
deleteCookie (string $name, ?string $path=null, ?string $domain=null, ?bool $secure=null): void
Usuwa cookie. Domyślne wartości parametrów to:
$pathz zasięgiem na wszystkie katalogi ('/')$domainz zasięgiem na bieżącą (sub)domenę, ale nie jej subdomeny$securezależy od ustawień w konfiguracji
$httpResponse->deleteCookie('lang');
Nette\Http\Context
Obiekt Nette\Http\Context łączy żądanie i odpowiedź razem i pomaga przy cache HTTP. Nie jest zarejestrowany jako usługa, więc tworzysz go sam. W presenterach zwykle łatwiej użyć metody lastModified(); kontekst przydaje się, gdy odpowiedź wysyłasz sam, na przykład z własnej klasy odpowiedzi.
isModified (string|int|\DateTimeInterface|null $lastModified=null, ?string $etag=null): bool
Ustala, czy treść zmieniła się od ostatniej wizyty klienta. Jeśli przekażesz czas ostatniej modyfikacji, wysyła
nagłówek Last-Modified; jeśli przekażesz walidator ETag (krótki ciąg identyfikujący bieżącą wersję
treści, np. jej hash), wysyła nagłówek ETag. Następnie porównuje oba z nagłówkami
If-Modified-Since i If-None-Match wysłanymi przez przeglądarkę.
Jeśli przeglądarka ma już pasującą wersję, metoda ustawia kod 304 Not Modified i zwraca false:
w takim przypadku w ogóle nie wysyłaj ciała odpowiedzi. W przeciwnym razie zwraca 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 są opcjonalne. Jeśli nie znasz czasu modyfikacji treści, użyj tylko ETag i odwrotnie.