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().

Instalacja i wymagania

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:

  • $path z zasięgiem na wszystkie katalogi ('/')
  • $domain z zasięgiem na bieżącą (sub)domenę, ale nie jej subdomeny
  • $secure zależ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.

wersja: 4.x