Risposta HTTP
Nette incapsula la risposta HTTP in oggetti con un'API chiara.
La risposta HTTP è rappresentata dall'oggetto Nette\Http\Response. Se lavorate con Nette, questo oggetto
viene creato automaticamente dal framework e potete farvelo passare con la dependency injection. Nei presenter basta chiamare
il metodo $this->getHttpResponse().
Nette\Http\Response
A differenza di Nette\Http\Request, questo oggetto è mutabile, quindi
potete cambiarne lo stato con i setter, per esempio per inviare gli header. Ricordate che tutti i setter vanno chiamati prima
che venga inviato qualsiasi output. Il metodo isSent() dice se l'output è già stato inviato. Se restituisce
true, ogni tentativo di inviare un header lancia una Nette\InvalidStateException.
setCode (int $code, ?string $reason=null)
Cambia il codice di stato della risposta. Per una migliore leggibilità del codice sorgente si consiglia di usare le costanti predefinite invece dei numeri veri e propri.
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
getCode(): int
Restituisce il codice di stato della risposta.
isSent(): bool
Restituisce se gli header sono già stati inviati dal server al browser, cioè se non è più possibile inviare header o cambiare il codice di stato.
setHeader (string $name, ?string $value)
Invia un header HTTP e sovrascrive l'header dello stesso nome inviato in precedenza. Se $value è
null, l'header viene rimosso.
$httpResponse->setHeader('Pragma', 'no-cache');
addHeader (string $name, string $value)
Invia un header HTTP e non sovrascrive l'header dello stesso nome inviato in precedenza.
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
deleteHeader (string $name)
Cancella un header HTTP inviato in precedenza.
getHeader (string $header): ?string
Restituisce l'header HTTP inviato oppure null se non esiste. Il parametro non fa distinzione tra maiuscole e
minuscole.
$pragma = $httpResponse->getHeader('Pragma');
getHeaders(): array<string, string>
Restituisce tutti gli header HTTP inviati come array associativo.
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
setContentType (string $type, ?string $charset=null)
Cambia l'header Content-Type.
$httpResponse->setContentType('text/plain', 'UTF-8');
redirect (string $url, int $code=self::S302_Found): void
Reindirizza a un altro URL. Ricordate di terminare poi lo script.
$httpResponse->redirect('http://example.com');
exit;
setExpiration (?string $expire)
Imposta la scadenza del documento HTTP con gli header Cache-Control e Expires. Il parametro è un
intervallo di tempo (come testo) oppure null, che disattiva la cache.
// la cache del browser scade tra un'ora
$httpResponse->setExpiration('1 hour');
sendAsFile (string $fileName)
La risposta verrà scaricata tramite la finestra Salva con nome con il nome indicato. Non invia il file stesso.
$httpResponse->sendAsFile('fattura.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)
Invia un cookie. Valori predefiniti dei parametri:
$path |
'/' |
il cookie è disponibile per tutti i percorsi del (sotto)dominio (configurabile) |
$domain |
null |
cioè disponibile per il (sotto)dominio corrente, ma non per i suoi sottodomini (configurabile) |
$secure |
auto |
true se il sito gira su HTTPS, altrimenti false (valore predefinito del framework; la classe da sola
usa false) (configurabile) |
$httpOnly |
true |
il cookie non è accessibile a JavaScript |
$sameSite |
'Lax' |
il cookie può non essere inviato durante l'accesso cross-origin |
$partitioned |
false |
se il cookie è partizionato, vedi sotto (dalla v3.4) |
I valori predefiniti dei parametri $path, $domain e $secure li potete cambiare nella configurazione.
La scadenza si passa come numero di secondi, come intervallo o data testuale, oppure come oggetto
DateTimeInterface. Il valore null crea un cookie di sessione, che il browser scarta alla chiusura. Nette
invia la scadenza sia nell'attributo Expires sia in Max-Age.
$httpResponse->setCookie('lang', 'it', '100 days'); // scade tra 100 giorni
$httpResponse->setCookie('lang', 'it', null); // cookie di sessione
Il parametro $domain determina quali domini possono accettare il cookie. Se non è indicato, il cookie viene
accettato dallo stesso (sotto)dominio che lo ha impostato, ma non dai suoi sottodomini. Se $domain è indicato, sono
compresi anche i sottodomini. Indicare $domain è quindi meno restrittivo che ometterlo. Con
$domain = 'nette.org', per esempio, i cookie sono disponibili anche su tutti i sottodomini come
doc.nette.org.
Il valore $sameSite lo potete passare come enum Nette\Http\SameSite: SameSite::Lax,
SameSite::Strict oppure SameSite::None (funzionano anche i valori stringa 'Lax',
'Strict', 'None'). Se impostate SameSite::None, l'attributo $secure si attiva
automaticamente, perché i browser rifiutano un cookie SameSite=None che non sia sicuro.
I cookie partizionati (CHIPS) danno al cookie uno spazio di archiviazione separato per ogni sito di primo
livello. Quando quindi un servizio di terze parti (per esempio un widget incorporato) imposta un cookie partizionato, il browser
ne conserva una copia distinta per ogni sito in cui il widget compare, e queste copie non si possono collegare tra loro per il
tracciamento cross-site. Lo attivate impostando $partitioned a true; richiede anche l'attributo
$secure, che perciò si attiva automaticamente.
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
deleteCookie (string $name, ?string $path=null, ?string $domain=null, ?bool $secure=null): void
Cancella un cookie. I valori predefiniti dei parametri sono:
$pathcon ambito su tutte le directory ('/')$domaincon ambito sul (sotto)dominio corrente, ma non sui suoi sottodomini$securedipende dalle impostazioni nella configurazione
$httpResponse->deleteCookie('lang');
Nette\Http\Context
L'oggetto Nette\Http\Context unisce la richiesta e la risposta e aiuta con la cache HTTP. Non è registrato come servizio, quindi ve lo create voi. Nei presenter di solito è più comodo usare il metodo lastModified(); il context torna utile quando inviate la risposta da soli, per esempio da una vostra classe di risposta.
isModified (string|int|\DateTimeInterface|null $lastModified=null, ?string $etag=null): bool
Determina se il contenuto è cambiato dall'ultima visita del client. Se passate l'ora dell'ultima modifica, invia l'header
Last-Modified; se passate un validatore ETag (una breve stringa che identifica la versione attuale del contenuto, per
esempio il suo hash), invia l'header ETag. Poi li confronta con gli header If-Modified-Since e
If-None-Match inviati dal browser.
Se il browser ha già una versione corrispondente, il metodo imposta il codice 304 Not Modified e restituisce
false: in tal caso non inviate affatto il corpo della risposta. Altrimenti restituisce 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);
}
}
Entrambi i parametri sono opzionali. Se non conoscete l'ora di modifica del contenuto, usate solo l'ETag, e viceversa.