Respuesta HTTP
Nette encapsula la respuesta HTTP en objetos con una API clara.
La respuesta HTTP está representada por el objeto Nette\Http\Response. Si trabaja con Nette, el framework crea
este objeto automáticamente y puede hacer que se lo pasen mediante inyección de dependencias. En los presenters basta
con llamar al método $this->getHttpResponse().
Nette\Http\Response
A diferencia de Nette\Http\Request, este objeto es mutable, así que puede
usar setters para cambiar el estado, p. ej. para enviar cabeceras. Recuerde que todos los setters deben llamarse antes de
enviar cualquier salida real. El método isSent() indica si la salida ya se ha enviado. Si devuelve
true, cualquier intento de enviar una cabecera lanzará una Nette\InvalidStateException.
setCode (int $code, ?string $reason=null)
Cambia el código de estado de la respuesta. Para que el código fuente se lea mejor, se recomienda usar las constantes predefinidas en lugar de los números.
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
getCode(): int
Devuelve el código de estado de la respuesta.
isSent(): bool
Devuelve si ya se han enviado las cabeceras del servidor al navegador, lo que significa que ya no es posible enviar cabeceras ni cambiar el código de estado.
setHeader (string $name, ?string $value)
Envía una cabecera HTTP y sobrescribe la cabecera del mismo nombre enviada antes. Si $value es
null, la cabecera se elimina.
$httpResponse->setHeader('Pragma', 'no-cache');
addHeader (string $name, string $value)
Envía una cabecera HTTP y no sobrescribe la cabecera del mismo nombre enviada antes.
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
deleteHeader (string $name)
Borra una cabecera HTTP enviada antes.
getHeader (string $header): ?string
Devuelve la cabecera HTTP enviada, o null si no existe. El parámetro no distingue mayúsculas de minúsculas.
$pragma = $httpResponse->getHeader('Pragma');
getHeaders(): array<string, string>
Devuelve todas las cabeceras HTTP enviadas como array asociativo.
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
setContentType (string $type, ?string $charset=null)
Cambia la cabecera Content-Type.
$httpResponse->setContentType('text/plain', 'UTF-8');
redirect (string $url, int $code=self::S302_Found): void
Redirige a otra URL. Recuerde terminar el script después.
$httpResponse->redirect('http://example.com');
exit;
setExpiration (?string $expire)
Establece la expiración del documento HTTP mediante las cabeceras Cache-Control y Expires. El
parámetro es un intervalo de tiempo (como texto) o null, que desactiva la caché.
// la caché del navegador expira en una hora
$httpResponse->setExpiration('1 hour');
sendAsFile (string $fileName)
La respuesta se descargará mediante un cuadro de diálogo Guardar como con el nombre indicado. No envía el archivo en sí.
$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)
Envía una cookie. Valores predeterminados de los parámetros:
$path |
'/' |
la cookie está disponible para todas las rutas del (sub)dominio (configurable) |
$domain |
null |
es decir, disponible para el (sub)dominio actual, pero no para sus subdominios (configurable) |
$secure |
auto |
true si el sitio funciona con HTTPS, si no false (predeterminado del framework; la clase por sí
sola usa false) (configurable) |
$httpOnly |
true |
la cookie es inaccesible para JavaScript |
$sameSite |
'Lax' |
la cookie puede no enviarse en un acceso cross-origin |
$partitioned |
false |
si la cookie está particionada, véase abajo (desde la v3.4) |
Puede cambiar los valores predeterminados de los parámetros $path, $domain y $secure en
la configuración.
La expiración se pasa como número de segundos, como intervalo o fecha en texto, o como objeto
DateTimeInterface. El valor null crea una cookie de sesión, que el navegador descarta al cerrarse.
Nette envía la expiración tanto en el atributo Expires como en Max-Age.
$httpResponse->setCookie('lang', 'en', '100 days'); // expira en 100 días
$httpResponse->setCookie('lang', 'en', null); // cookie de sesión
El parámetro $domain determina qué dominios pueden aceptar la cookie. Si no se indica, la cookie la acepta el
mismo (sub)dominio que la estableció, pero no sus subdominios. Si se indica $domain, se incluyen también los
subdominios. Por eso, indicar $domain es menos restrictivo que omitirlo. Por ejemplo, con
$domain = 'nette.org' las cookies están disponibles también en todos los subdominios, como
doc.nette.org.
Puede pasar el valor de $sameSite como enum Nette\Http\SameSite: SameSite::Lax,
SameSite::Strict o SameSite::None (los valores de cadena 'Lax', 'Strict',
'None' también funcionan). Si lo pone a SameSite::None, el atributo $secure se activa
automáticamente, porque los navegadores rechazan una cookie SameSite=None que no sea segura.
Las cookies particionadas (CHIPS) le dan a una cookie su propio almacén separado para cada sitio de nivel
superior. Así, cuando un servicio de terceros (como un widget incrustado) establece una cookie particionada, el navegador guarda
una copia distinta para cada sitio en el que aparece el widget, y esas copias no se pueden enlazar entre sí para el seguimiento
entre sitios. Actívelas poniendo $partitioned a true; esto requiere además el atributo
$secure, así que se activa automáticamente.
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
deleteCookie (string $name, ?string $path=null, ?string $domain=null, ?bool $secure=null): void
Borra una cookie. Los valores predeterminados de los parámetros son:
$pathcon alcance a todos los directorios ('/')$domaincon alcance al (sub)dominio actual, pero no a sus subdominios$securedepende de los ajustes de la configuración
$httpResponse->deleteCookie('lang');
Nette\Http\Context
El objeto Nette\Http\Context une la petición y la respuesta y ayuda con la caché HTTP. No está registrado como servicio, así que lo crea usted mismo. En los presenters suele ser más fácil usar el método lastModified(); el contexto resulta útil cuando envía la respuesta usted mismo, por ejemplo desde su propia clase de respuesta.
isModified (string|int|\DateTimeInterface|null $lastModified=null, ?string $etag=null): bool
Determina si el contenido ha cambiado desde la última visita del cliente. Si le pasa la hora de la última modificación,
envía la cabecera Last-Modified; si le pasa un validador ETag (una cadena corta que identifica la versión actual
del contenido, p. ej. su hash), envía la cabecera ETag. Después compara ambos con las cabeceras
If-Modified-Since e If-None-Match que envió el navegador.
Si el navegador ya tiene una versión coincidente, el método establece el código 304 Not Modified y devuelve
false; en ese caso no envíe el cuerpo de la respuesta en absoluto. En caso contrario devuelve 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);
}
}
Ambos parámetros son opcionales. Si no conoce la hora de modificación del contenido, use solo el ETag, y al revés.