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

Installazione e requisiti

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:

  • $path con ambito su tutte le directory ('/')
  • $domain con ambito sul (sotto)dominio corrente, ma non sui suoi sottodomini
  • $secure dipende 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.

versione: 4.x