El nacimiento de las galletas
Dado que el protocolo HTTP es estatoso, los servicios del lado del servidor deben ser con estado. El propósito original del nacimiento de las cookies era almacenar información de estado en la web para usar fácilmente en el lado del servidor. Por ejemplo, determine si el usuario está visitando el sitio web por primera vez. La última especificación es RFC 6265, que es una especificación implementada por los servidores de navegador.
El procesamiento de las cookies se divide en:
El servidor envía cookies como el cliente
El navegador guarda cookies
Después de eso, cada vez que se solicite la solicitud HTTP, el navegador enviará la cookie al servidor.
Enviar y analizar en el lado del servidor
Enviar galletas
Las cookies del lado del servidor enviadas por el cliente se implementan a través de paquetes de respuesta HTTP. En los cocineros, las cookies que deben ser enviadas por el cliente se establecen. El formato de cookie es el siguiente:
Set-cookie: "name = value; domain = .domain.com; path =/; expires = sat, 11 de junio de 2016 11:29:42 gmt; httponly; seguro"
Donde el nombre = valor es una opción requerida, y otros son opcionales. Los componentes principales de las cookies son los siguientes:
Nombre: un nombre de cookie único y definitivo. En términos generales, el nombre de una cookie es insensible al caso.
Valor: el valor de cadena almacenado en la cookie. Es mejor codificar la URL el nombre y el valor de la cookie
Dominio: la cookie es válida para qué dominio. Todas las solicitudes enviadas a este dominio contendrán esta información de cookies. Este valor puede contener subdominios (como:
yq.aliyun.com) o no se puede incluir (por ejemplo: .aliyun.com, es válido para todos los subdominios de aliyun.com).
Ruta: indica la ruta afectada por esta cookie. El navegador enviará cookies en función de esta configuración, como la coincidencia de ruta en el dominio especificado.
Expira: tiempo de vencimiento, marca de tiempo que indica cuándo se debe eliminar la cookie (es decir, cuándo se debe dejar de enviar a la cookie al servidor). Si no establece esta marca de tiempo, el navegador eliminará todas las cookies cuando la página esté cerrada; Sin embargo, también puede establecer el tiempo de eliminación usted mismo. Este valor está en el formato de tiempo GMT. Si el tiempo del cliente y el servidor son inconsistentes, habrá desviaciones al usar expiras.
La edad máxima: la misma función que expira, se usa para decirle al navegador cuánto tiempo expira esta cookie (en segundos), en lugar de un punto de tiempo fijo. En circunstancias normales, la edad máxima tiene mayor prioridad que expirada.
Httponly: informa al navegador que no permita que el script document.cookie cambie este valor, y este valor tampoco es visible en document.cookie. Pero esta cookie aún se llevará a cabo en la solicitud HTTP. Tenga en cuenta que aunque este valor no está disponible en el script, todavía existe en el directorio de instalación del navegador como un archivo. Esta configuración generalmente se establece en el lado del servidor.
Secure: Bandero de seguridad, después de especificar, solo se puede enviar al servidor cuando se usa el enlace SSL. Si se trata de un enlace HTTP, esta información no se aprobará. Incluso si se establece el atributo seguro, no significa que otros no puedan ver la información de cookies guardada localmente en su máquina, por lo que no ponga información importante en las cookies y la configure en el lado del servidor.
Los ejemplos de cookies son los siguientes:
var http = require ('http'); var fs = require ('fs'); http.createServer (function (req, res) {res.setheader ('status', '200 ok'); res.setheader ('set-cookie', 'isVisit = true; domain = .YourMain.com; sath =/; max-age' = 1000 '; res.wrwruite World ');Configurar el conjunto de cookie directamente es demasiado original. Podemos encapsular el proceso de configuración de cookies de la siguiente manera:
var serily = function (nombre, val, opciones) {if (! name) {tire nuevo error ("Cooleie debe tener nombre"); } var enc = encodeuricOponent; VAR Parts = []; val = (val! == null && val! == Undefined)? val.ToString (): ""; Opciones = Opciones || {}; parts.push (enc (nombre) + "=" + enc (val)); // debe haber dos puntos en el dominio if (options.domain) {parts.push ("domain =" + options.domain); } if (options.path) {parts.push ("path =" + options.path); } // Si no establece expiras y los navegadores de edad máxima borrarán cookies cuando la página esté cerrada si (opciones.expires) {parts.push ("expires =" + options.expires.togmtstring ()); } if (options.maxage && typeof options.maxage === "número") {parts.push ("max -ge =" + options.maxage); } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("seguro"); } return parts.Join (";");}Cabe señalar que si una cookie está configurada en un momento pasado, el navegador eliminará la cookie de inmediato; Además, el elemento de dominio debe tener dos puntos, por lo que no se puede establecer en localhost:
Algo que no me dejó claro aquí y que me confundió por un tiempo fue que los nombres de dominio deben contener al menos dos puntos (.), ¡Por lo tanto, 'localhost' no es válido y el navegador se negará a establecer la galleta!
Cookies de análisis del lado del servidor
Las cookies pueden establecer diferentes dominios y rutas, por lo que para el mismo valor de nombre, se puede repetir en diferentes rutas en diferentes dominios y diferentes rutas. El navegador ordenará el pedido en el pedido que mejor coincida con la URL o la dirección de página solicitada actual.
Entonces, cuando la cookie pasó al lado del servidor en el lado actual tiene múltiples valores de nombre duplicados, solo necesitamos la que más coincida, es decir, la primera. El código de análisis del lado del servidor es el siguiente:
var parse = function (cstr) {if (! cstr) {return null; } var dec = decodeuricponent; var cookies = {}; var partes = cstr.split (// s*;/s*/g); parts.forEach (function (p) {var pos = p.indexof ('='); // El nombre y el valor deben codificarse antes de que la cookie se almacene var name = pos> -1? dec (p.substr (0, pos)): p; var val = pos> -1? dec (p.substr (pos + 1)): null; // solo necesitas obtener la mayoría de las cookies. cookies [name] = val;}/* else if (! regresar cookies;}Acceso al cliente
El navegador gestiona las cookies pasadas en segundo plano y permite a los desarrolladores usar documentos.cookies en JavaScript para acceder a las cookies. Pero esta interfaz es muy cojo de usar. Mostrará diferentes comportamientos debido a las diferentes formas en que se usa.
Cuando se usa para obtener valores de atributos, Document.cookie devuelve todas las cadenas disponibles en la página actual (según el dominio de la cookie, la ruta, el tiempo de vencimiento y la configuración de seguridad). El formato de la cadena es el siguiente:
"name1 = value1; name2 = value2; name3 = value3";
Cuando se usa para establecer valores, la propiedad Document.cookie se puede configurar en una nueva cadena de cookies. Esta cadena se interpreta y se agrega a la colección de cookies existente. como:
document.cookie = "_fa = aaaffffasdsf; domain = .dojotoolkit.org; path =/"
Configurar document.cookie no anula las cookies a menos que la ruta del dominio del valor del nombre establecido se repita con una cookie existente.
Dado que es muy inconveniente leer y escribir cookies, podemos encapsular algunas funciones para manejar cookies, principalmente para la adición, modificación y eliminación de cookies.
var cookieUtils = {get: function (name) {var Cookiename = Encodeuricomponent (name) + "="; // solo obtenga el nombre más coincidente, valor var cookiestart = document.cookie.indexof (Cookiename); var cookievalue = nulo; if (CookeStart> -1) {// de Cookestart var cookieend = document.cookie.indexof (';', CookeStart); // from = after = (cookieend> -1) {cookievalue = decodeuricponent (document.cookie.substring (CookeStart + Cookiename.length, Cookieend)); } else {Cookievalue = DecodeuriComponent (document.cookie.substring (CookeStart + Cookiename.length, document.cookie.length)); }} return cookievalue; }, set: function (nombre, val, opciones) {if (! name) {tirar un nuevo error ("Cooliie debe tener nombre"); } var enc = encodeuricOponent; VAR Parts = []; val = (val! == null && val! == Undefined)? val.ToString (): ""; Opciones = Opciones || {}; parts.push (enc (nombre) + "=" + enc (val)); // El dominio debe contener dos puntos if (options.domain) {parts.push ("domain =" + options.domain); } if (options.path) {parts.push ("path =" + options.path); } // Si no establece expiras y el navegador de edad máxima borrará las cookies cuando la página esté cerrada si (opciones.expires) {parts.push ("expires =" + options.path); } // Si no establece expiras y el navegador de edad máxima borrará cookies cuando la página esté cerrada si (opciones.expires) {parts.push ("expires =" + options.expires.togmtstring ()); } if (options.maxage && typeof options.maxage === "número") {parts.push ("max -ge =" + options.maxage); } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("seguro"); } document.cookie = parts.Join (";"); }, eliminar: function (nombre, opciones) {options.expires = new Date (0); // Establecer en la fecha anterior this.set (nombre, nulo, opciones); }}Ventajas del almacenamiento en caché
El caché web comúnmente denominado se refiere a un dispositivo HTTP que puede guardar automáticamente copias de las solicitudes HTTP comunes. Para los desarrolladores de front-end, los navegadores juegan un papel importante. Además, hay varios servidores proxy comunes que también se pueden usar para el almacenamiento en caché. Cuando una solicitud web llega al caché, el caché extrae el contenido de réplica de la réplica local sin pasar por el servidor. Esto trae las siguientes ventajas:
El almacenamiento en caché reduce la transmisión de datos redundante y ahorra tráfico
El caché alivia los problemas de cuello de botella de ancho de banda. Las páginas se pueden cargar más rápido sin más ancho de banda
El caché alivia la congestión instantánea y reduce los requisitos para el servidor original.
El caché reduce el retraso de distancia porque las páginas de carga de lugares más lentos serán más lentos.
Tipo de caché
El caché puede dedicarse a un solo usuario o compartido por varios usuarios. Un caché dedicado se llama caché privado, y un caché compartido se llama caché público.
Caché privado
El caché privado es solo para usuarios propietarios, por lo que no requiere mucho espacio y es barato. Los navegadores web tienen cachés privados incorporados: la mayoría de los navegadores almacenarán recursos comunes en el disco y la memoria de su PC. Por ejemplo, la ubicación de almacenamiento de caché del navegador Chrome es: C:/Users/Your_account/AppData/local/Google/Chrome/User Data/Default.
Caché
Los cachés públicos son servidores de proxy compartidos especiales, llamados servidores proxy de caché o cachés proxy (un propósito de proxy inverso). El caché público aceptará el acceso de múltiples usuarios, por lo que puede reducir mejor el tráfico redundante.
En la figura a continuación, cada cliente accederá repetidamente a un recurso al servidor (no está en la memoria caché privada en este momento), de modo que accederá al servidor varias veces, aumentando la presión del servidor. Al usar un caché público compartido, el caché solo necesita recuperarse del servidor una vez y no tiene que pasar por el servidor en el futuro, lo que puede reducir significativamente la presión en el servidor.
De hecho, el caché público jerárquico generalmente se usa en aplicaciones reales. La idea básica es usar cachés pequeños y baratos cerca del cliente, mientras que en un nivel superior, los cachés más grandes y más potentes se adoptan gradualmente para cargar recursos compartidos por múltiples usuarios.
Flujo de procesamiento de caché
Para los desarrolladores de front-end, tratamos principalmente de cachés en el navegador, por lo que el proceso anterior se simplifica para:
La siguiente imagen muestra los resultados de la solicitud de un sitio web para diferentes recursos. Se puede ver que algunos recursos se leen directamente desde el caché, algunos recursos se reverifican con el servidor y algunos recursos se readquisitan desde el servidor.
Tenga en cuenta que todas las preguntas que discutimos sobre los recursos de caché son solo para las solicitudes GET. Para operaciones de comportamiento como Post, Eliminar y Put, generalmente no hay caché.
Límite de frescura
HTTP conserva una copia del recurso del servidor durante un período de tiempo a través de la memoria caché, que se llama límite de frescura. Esto solicita el mismo recurso por un período de tiempo y no volverá a pasar por el servidor. Cache-Control y expira en el protocolo HTTP se puede usar para establecer el límite de frescura. El primero es el nuevo encabezado de respuesta agregado en HTTP1.1, y el segundo es el encabezado de respuesta en HTTP1.0. Ambos hacen lo mismo, pero dado que el control de caché usa el tiempo relativo, y expiras puede tener el problema de que el tiempo del cliente y el servidor es diferente, preferimos el control de caché.
Control de caché
Echemos un vistazo a qué valores de atributos se pueden establecer mediante el control de caché:
Max-Age (la unidad es s) Especifica el tiempo máximo válido para establecer el caché, que define el período de tiempo. Cuando el navegador envía una solicitud al servidor, el navegador ya no enviará una solicitud al servidor durante la edad máxima.
<html> <fead> <meta http-equiv = "content-type" content = "text /html; charset = utf-8"> <meta name = "viewport" content = "width = dispositivo-width, escala inicial = 1.0, maximum-scale = 1.0, user-scalable = no" /> <meta http-equiv = "x-Uecatible" Content = "Ie = Edge"/> <title> Web Cache </title> <Link Rel = "Actual icon" Href = "./ CASTCUT.PNG"> <Script> </script> </Et Head> <Body> <IMG src = "./ Cache.png"> </body> </html> var http = requerir ('http'); var fs =; requirir ('fs'); http.createServer (function (req, res) {if (req.url === '/' || req.url ==== '' || req.url === '/index.html') {fs.Readfile ('./ index.html', function (err, file) {consoly.log (req.Url) Para el documento principal, res.setheader ('Cache-Control', "No-Cache, AGE =" + 5); fs.ReadFile ('./ Cache.png', function (err, file) {res.setheader ('cache-confontrol', "max-age =" + 5); // cache cinco segundos res.setheader ('content-type', 'images/png'); res.writehead ('200', "no modificado"); }). Escuchar (8888)Cuando se accede a la página por segunda vez en 5 segundos, el navegador obtendrá directamente recursos de la memoria caché
Public especifica que la respuesta puede almacenarse en caché en el caché proxy y, por lo tanto, puede ser compartido por múltiples usuarios. Si el privado no se especifica explícitamente, es predeterminado al público.
La respuesta privada solo se puede almacenar en caché en el caché privado y no se puede colocar en el caché proxy. Los recursos que son sensibles a alguna información del usuario generalmente deben establecerse en privado.
No-Cache significa que primero debe confirmar con el servidor si el recurso ha sido cambiado (dependiendo de IF NONE-Match y EtAG) antes de decidir si usar caché local.
Si el procesamiento anterior de Cache.png se cambia a lo siguiente, cada vez que visita la página, el navegador debe ir al servidor para verificar si el recurso ha sido cambiado.
fs.ReadFile ('./ cache.png', function (err, file) {console.log (req.headers); console.log (req.url) if (! req.headers ['if-none-match']) {res.setheader ('cache-confontrol', "No-cache, max-eage =" + 5); res.setheader ('' ', concentrado', contentere ». 'Images/png'); res.setHeader ('Cache-Control', "AGEA MAX =" + 5);Sin tienda prohíbe absolutamente caché de cualquier recurso, lo que significa que cada vez que el usuario solicite el recurso, se enviará una solicitud al servidor y el recurso completo se descargará cada vez. Generalmente se usa para recursos confidenciales.
Con respecto al uso del control de caché, vea la imagen a continuación (de grandes cantidades)
Límite de frescura del cliente
El control de caché no solo se puede configurar en el encabezado de respuesta, sino también en el encabezado de solicitud. El navegador puede decidir si leer recursos del caché estableciendo el control de caché en el encabezado de solicitud. Esta es también la razón por la cual a veces hacer clic en el botón de actualización del navegador e ingresar en la barra de direcciones para ver resultados completamente diferentes en el módulo de red
Expirar
No se recomienda expirarse, especifica una fecha de vencimiento específica en lugar de varios segundos. Debido a que muchos servidores y clientes tienen un reloj inconsistente, es mejor usar el control de caché.
Verificación del servidor
El recurso almacenado en caché en el navegador o el caché proxy caduca no significa que en realidad sea diferente de los recursos en el servidor original, sino que solo significa que es hora de verificar. Esta situación se llama reverificación del servidor.
Si el recurso cambia, debe obtener nuevos recursos y reemplazar los recursos antiguos en el caché.
Si el recurso no ha cambiado, el caché solo necesita obtener un nuevo encabezado de respuesta y un nuevo tiempo de vencimiento para actualizar el tiempo de vencimiento del recurso en el caché.
El método de verificación recomendado para HTTP1.1 es IF-NONE-MATCH/ETAG, y IF Modificado-Since/Last-Modified se usa en HTTP1.0.
Etag e if-none-partido
Genere una cadena hash basada en el contenido de la entidad, identificando el estado del recurso y es generado por el servidor. El navegador volverá a pasar esta cadena al servidor para verificar que el recurso haya sido modificado. Si no se ha modificado, el proceso es el siguiente (la imagen proviene de una breve discusión sobre el caché web):
En la demostración anterior, hemos visto cómo verificar ETAG en el servidor:
Dado que ETAG tiene una estructura de servidor, la singularidad de ETAG debe garantizarse en el entorno de clúster
Si modifica a sínss vs. Último modificado
Estos dos son encabezados de solicitud/respuesta utilizados en HTTP 1.0 para verificar si el recurso ha expirado. Estos dos encabezados son fechas. El proceso de verificación es similar al ETAG, por lo que no lo presentaremos en detalle aquí. Al usar estos dos encabezados para verificar que el recurso se actualice, existen los siguientes problemas:
Algunos recursos de documentos se reescriben periódicamente, pero el contenido real no ha cambiado. En este momento, los metadatos del archivo mostrarán que la fecha de modificación más reciente del archivo es diferente de si modificó, lo que resulta en respuestas innecesarias.
Se han modificado algunos recursos de documentos, pero el contenido de la modificación no es importante, y no se requiere que todos los cachés se actualicen (como los comentarios del código)
Con respecto a la actualización de Cache, consulte la respuesta de Zhang Yunlong aquí. Este artículo no se ampliará en detalle.
El código de demostración en este artículo es el siguiente:
<! DocType html> <html> <fead> <meta http-equiv = "content-type" content = "text /html; charset = utf-8"> <meta name = "viewport" content = "width = dispositivo-width, inicial-escale = 1.0, maximum-scale = 1.0, user-scalable = no" /> <meta http-equiv = "x-ua-compatible" content = "ie = edge"/> <title> Web Cache </title> <Link rel = "Acton icon" href = "./ shortcut.png"> <script> </script> </head> <body> <img src = "./ cache.png"> </body> </html> requirir ('http'); var fs = require ('fs'); http.createServer (function (req, res) {if (req.url ==== '/' || req.url ==== '' || req.url === '/index.html') {fs.ladfile ('./xic.html', free (file, file). Console.log (req.url) // Establecer caché para el documento principal, sin efecto. === '/ShortCut.png') {fs.ReadFile ('./Cortcut.png', function (err, archivo) {console.log (req.url) res.setheader ('content-type', 'images/png'); res.writehead ('200', "ok"); res.end (file);}}} (req.url '/cache.png') {fs.ReadFile ('./ cache.png', function (err, file) {console.log (req.headers); console.log (req.url) if (! req.headers ['if-non-match']) {res.setheader ('cache-confirl', "max-age =" " +" + 5); res.setHeader ('Content-type', 'Images/png'); res.end (); }}). Escuchar (8888)Ok, la introducción de este artículo a las cookies termina aquí, espero que a todos les guste.