Рождение печенья
Поскольку протокол HTTP является без сохранения состояния, серверные службы должны быть состоятельными. Первоначальная цель рождения файлов cookie состояла в том, чтобы хранить информацию о состоянии в Интернете для легкого использования на стороне сервера. Например, определите, посещает ли пользователь веб -сайт в первый раз. Последняя спецификация - RFC 6265, которая является спецификацией, реализованной серверами браузеров.
Обработка файлов cookie разделена на:
Сервер отправляет файлы cookie, как клиент
Браузер экономит печенье
После этого каждый раз, когда запрошен HTTP -запрос, браузер отправляет файл cookie на сервер.
Отправить и анализировать на стороне сервера
Отправить файлы cookie
Серверные файлы cookie, отправленные клиентом, реализуются через пакеты ответов HTTP. В Set-Cookies созданы файлы cookie, которые необходимо отправлять клиентом. Формат печенья выглядит следующим образом:
SET-COOKIE: "name = value; domain = .domain.com; path =/; истекает = sat, 11 июня 2016 г. 11:29:42 Gmt; httponly; безопасное"
Где имя = значение является обязательным вариантом, а другие - необязательны. Основные компоненты файлов cookie заключаются в следующем:
Имя: уникальное и определенное имя печенья. Вообще говоря, имя печенья нечувствительно.
Значение: строковое значение, сохраненное в файле cookie. Лучше всего URL кодировать название и значение cookie
Домен: Cookie верен, для которого домен. Все запросы, отправленные в этот домен, будут содержать эту информацию о файле cookie. Это значение может содержать субдомен (например:
yq.aliyun.com) или он не может быть включен (например: .aliyun.com, он действителен для всех субдоменов aliyun.com).
Путь: указывает на путь, затронутый этим печеньем. Браузер отправит файлы cookie на основе этой конфигурации, например, сопоставление пути в указанном домене.
Срок действия истечения: время истечения, временная метка, указывающая, когда следует удалить cookie (то есть, когда файл cookie следует остановить отправку на сервер). Если вы не установите эту метку времени, браузер удалит все файлы cookie, когда страница будет закрыта; Тем не менее, вы также можете установить время удаления самостоятельно. Это значение находится в формате времени GMT. Если клиент и время сервера не соответствует, при использовании истекают отклонения.
Max-Age: та же функция, что и истекает, используется для рассказа о браузере, сколько времени истекает (в секунды), а не фиксированный момент времени. При нормальных обстоятельствах Max-Age имеет более высокий приоритет, чем истекает.
Httponly: информирует браузер, чтобы не разрешать сценарию Document.cookie изменить это значение, и это значение также не видно в Document.cookie. Но этот файл cookie все еще будет нести по HTTP -запросу. Обратите внимание, что, хотя это значение недоступно в скрипте, оно все еще существует в каталоге установки браузера в качестве файла. Этот параметр обычно устанавливается на стороне сервера.
Безопасно: флаг безопасности, после указания, он может быть отправлен на сервер только при использовании ссылки SSL. Если это ссылка HTTP, эта информация не будет передана. Даже если устанавливается безопасный атрибут, это не означает, что другие не могут видеть информацию о файле cookie, сохраненную локально на вашей машине, поэтому не вкладывайте важную информацию в файлы cookie и устанавливайте ее прямо на стороне сервера.
Примеры файлов cookie заключаются в следующем:
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 = .yourdomid.com; World ');Настройка Set-Cookie напрямую слишком оригинально. Мы можем инкапсулировать процесс настройки cookie следующим образом:
var serize = function (name, val, options) {if (! name) {бросить новую ошибку ("cooleie должен иметь имя"); } var enc = encodeuricomponent; var parts = []; val = (val! == null && val! == не определен)? val.tostring (): ""; Параметры = Параметры || {}; parts.push (enc (name) + "=" + enc (val)); // В домене должно быть две точки if (options.domain) {parts.push ("domain =" + options.domain); } if (options.path) {parts.push ("path =" + options.path); } // Если вы не устанавливаете истекает, и браузеры Max-Age будут очищать файлы cookie, когда страница будет закрыта, если (опции. } if (options.maxage && typeof options.maxage === "number") {parts.push ("max-age =" + options.maxage); } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("secure"); } return parts.join (";");}Следует отметить, что, если файл cookie устанавливается в прошлое, браузер немедленно удалит печенье; Кроме того, элемент домена должен иметь две точки, поэтому он не может быть установлен на Localhost:
Что -то, что мне здесь не было ясным и некоторое время смутило меня, так это то, что доменные имена должны содержать как минимум две точки (.), Следовательно, «Localhost» недействителен, и браузер откажется от установки cookie!
Серверный анализ файлов cookie
Файлы cookie могут устанавливать разные домены и пути, поэтому для одинакового значения имени его можно повторить в разных путях в разных областях и в разных путях. Браузер сортирует заказ в порядке, который лучше всего соответствует текущему запрошенному URL -адресу или адресу страницы.
Поэтому, когда файл cookie перешел на сторону сервера на текущей стороне, имеет несколько дублирующих значений имен, нам нужен только тот, который соответствует больше всего, то есть первым. Код анализа сервера выглядит следующим образом:
var parse = function (cstr) {if (! cstr) {return null; } var dec = decodeuricomponent; var cookies = {}; var parts = cstr.split (// s*;/s*/g); parts.foreach (function (p) {var pos = p.indexof ('='); // имя и значение должны быть кодированы до того, как файл cookie будет сохранен var name = -1? dec (p.substr (0, pos)): p; var val = pos> -1? dec (p.substr (pos + 1)): null; // Только вам нужно получить наиболее матч -матч. cookie [name] = val; вернуть cookies;}Клиентский доступ
Браузер управляет файлами cookie, пройденными в фоновом режиме и позволяет разработчикам использовать Document.cookies в JavaScript для доступа к файлам cookie. Но этот интерфейс очень хромой для использования. Он будет показывать различное поведение из -за различных способов использования.
При использовании для получения значений атрибутов Document.cookie возвращает все строки, доступные на текущей странице (на основе домена, пути, времени и срока действия cookie). Формат строки заключается в следующем:
"name1 = value1; name2 = value2; name3 = value3";
При использовании для установки значений свойство Document.Cookie можно установить на новую строку cookie. Эта строка интерпретируется и добавляется в существующую коллекцию cookie. нравиться:
document.cookie = "_fa = aaafffasdsf; domain = .dojotoolkit.org; path =/"
Установка Document.COKIE не переопределяет файлы cookie, если не повторяется путь домена имени SET.
Поскольку очень неудобно читать и писать файлы cookie, мы можем инкапсулировать некоторые функции для обработки файлов cookie, в основном для добавления, модификации и удаления файлов cookie.
var cookieutils = {get: function (name) {var cookiename = encodeuricomponent (name) + "="; // Получить только наиболее подходящее имя, значение var cookieStart = document.cookie.indexof (cookiename); var cookievalue = null; if (cookieStart> -1) {// от cookieStart var cookieEend = document.cookie.indexof (';', cookiestart); // from = ATHE = (cookieEend> -1) {cookieievule = decodeuricomponent (document.cookie.substring (cookieStart + cookiename.length, cookieEend)); } else {cookievalue = decodeuricomponent (document.cookie.substring (cookieStart + cookiename.length, document.cookie.length)); }} вернуть cookievalue; }, set: function (name, val, options) {if (! name) {бросить новую ошибку ("cooliie должен иметь имя"); } var enc = encodeuricomponent; var parts = []; val = (val! == null && val! == не определен)? val.tostring (): ""; Параметры = Параметры || {}; parts.push (enc (name) + "=" + enc (val)); // Домен должен содержать две точки if (options.domain) {parts.push ("domain =" + options.domain); } if (options.path) {parts.push ("path =" + options.path); } // Если вы не устанавливаете истекает, и браузер Max-Age очистит файлы cookie, когда страница будет закрыта, если (опции. } // Если вы не устанавливаете истекает, и браузер Max-Age очистит файлы cookie, когда страница будет закрыта, если (options.expires) {parts.push ("expires =" + options.expires.togtstring ()); } if (options.maxage && typeof options.maxage === "number") {parts.push ("max-age =" + options.maxage); } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("secure"); } document.cookie = parts.join (";"); }, delete: function (name, options) {options.expires = new Date (0); // Установить на дату прошлого this.set (name, null, options); }}Преимущества кэширования
Обычно называемый веб -кэшем относится к устройству HTTP, которое может автоматически сохранять копии общих HTTP -запросов. Для фронтальных разработчиков браузеры играют важную роль. Кроме того, существуют различные общие прокси -серверы, которые также можно использовать для кэширования. Когда веб -запрос достигает кэша, кэш извлекает контент реплики из локальной копии, не проходя через сервер. Это приносит следующие преимущества:
Кэширование уменьшает избыточную передачу данных и экономит трафик
Кэш облегчает проблемы с узким местом полосы пропускания. Страницы могут быть загружены быстрее без большей полосы пропускания
Кэш облегчает мгновенные перегрузки и уменьшает требования для исходного сервера.
Кэш уменьшает задержку расстояния, потому что нагрузки из дальних мест будут медленнее.
Тип кеша
Кэш может быть посвящен одному пользователю или обмен несколькими пользователями. Выделенный кэш называется частным кешем, а общий кэш называется публичным кэшем.
Частный кеш
Частный кэш предназначен только для проприетарных пользователей, поэтому он не требует большого места и дешево. В веб -браузерах есть встроенные частные кэши - большинство браузеров будут кэшировать общие ресурсы на диске и памяти вашего ПК. Например, место хранения кэша в Chrome Browser: C:/users/your_account/appdata/local/google/chrome/пользователь данных/по умолчанию.
Публичный кеш
Общественные кэши - это специальные общие прокси -серверы, называемые прокси -серверами кэша или прокси -кэшами (цель обратного прокси). Общественный кэш примет доступ от нескольких пользователей, поэтому он может лучше сократить избыточный трафик.
На рисунке ниже каждый клиент будет многократно получать доступ к ресурсу на сервер (в настоящее время он не находится в частном кэше), чтобы он будет получать доступ к серверу несколько раз, увеличивая давление на сервер. При использовании общего общественного кеша кэш должен быть извлечен только один раз с сервера и не должен проходить через сервер в будущем, что может значительно снизить давление на сервер.
Фактически, иерархический общественный кэш обычно используется в реальных приложениях. Основная идея состоит в том, чтобы использовать небольшие и дешевые кэши вблизи клиента, в то время как на более высоком уровне более крупные и более мощные кэши постепенно принимаются для загрузки ресурсов, используемых несколькими пользователями.
Поток обработки кеша
Для разработчиков фронт-энда мы в основном имеем дело с кэшами в браузере, поэтому приведенный выше процесс упрощается до:
На следующей картинке показаны результаты запроса веб -сайта для различных ресурсов. Можно видеть, что некоторые ресурсы читаются непосредственно из кэша, некоторые ресурсы рецензируются с сервером, а некоторые ресурсы повторно приобретаются с сервера.
Обратите внимание, что все вопросы, которые мы обсуждали о ресурсах кэша, предназначены только для запросов. Для поведенческих операций, таких как Post, Delete и Pult, обычно нет кеша.
Предел свежести
HTTP сохраняет копию ресурса сервера в течение определенного периода времени через кэш, который называется пределом свежести. Это запрашивает тот же ресурс в течение определенного периода времени и больше не проходит через сервер. Контроль кеша и истечение срока действия в протоколе HTTP можно использовать для установки предела свежести. Первый - это новый заголовок ответа, добавленный в http1.1, а последний - заголовок ответа в http1.0. Оба делают одно и то же, но, поскольку Cache-Control использует относительное время, и истекает, и может возникнуть проблема с тем, что время клиента и сервера отличается, мы предпочитаем контроль за кешем.
Контроль кэша
Давайте посмотрим, какие значения атрибутов могут быть установлены с помощью Cache-Control:
Max-Age (Unit IS) Определяет максимальное допустимое время для установки кэша, который определяет продолжительность времени. Когда браузер отправляет запрос на сервер, браузер больше не будет отправлять запрос на сервер во время максимального возраста.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta http-equiv="X-UA-Compatible" content = "ie = Edge"/> <Title> Web Cache </title> <link rel = "icktcut icon" href = "./ shortcut.png"> <script> </script> </head> <body> <img src = "./ cache.png"> </body> </html> var htt require ('fs'); http.createserver (function (req, res) {if (req.url === '/' || req.url === '' || req.url === '/index.html') {fs.readfile ('./ Index.html', function (err, file). Кэш для основного документа, Res.Setheader ('Cache-Control', "No-Cache, Max-Age =" + 5); fs.readfile ('./ cache.png', function (err, file) {res.setheader ('cache-control', "max-age =" + 5); // caching пять секунд Res.setheader ('Content-type', 'Images/png'); Res.write ('200', не модифицировано "); }). Слушай (8888)Когда к странице обращается во второй раз в течение 5 секунд, браузер напрямую получит ресурсы из кэша
Public указывает, что ответ может быть кэширован в кэше прокси и поэтому может быть обмен несколькими пользователями. Если частное не указано явно, это по умолчанию по умолчанию публично.
Частный ответ может быть кэширован только в частном кэше и не может быть помещен в прокси -кэш. Ресурсы, которые чувствительны к какой -то пользовательской информации, обычно должны быть установлены на частную.
Безеш означает, что вы должны сначала подтвердить с сервером, был ли ресурс был изменен (полагаясь на if-none-match и etag), прежде чем решить, использовать ли локальный кэш.
Если вышеуказанная обработка cache.png изменяется на следующее, каждый раз, когда вы посещаете страницу, браузер должен перейти на сервер, чтобы проверить, был ли ресурс изменен.
fs.readfile ('./ cache.png', function (err, file) {console.log (req.headers); console.log (req.url) if (! req.headers ['if-none match']) {res.setheader ('cache-control', "no-cache, max-age =" + 5); «Изображения/PNG»; res.setheader ('Cache-Control', "max-age =" + 5);No Store Allower запрещает кэш любого ресурса, что означает, что каждый раз, когда пользователь запрашивает ресурс, запрос будет отправляться на сервер, а полный ресурс будет загружаться каждый раз. Обычно используется для конфиденциальных ресурсов.
Что касается использования контроля кеша, см. Рисунок ниже (из больших количеств)
Клиентский предел свежести
Контроль кэша может быть установлен не только в заголовке ответов, но и в заголовке запроса. Браузер может решить, следует ли читать ресурсы из кэша, установив контроль кэша в заголовке запроса. Именно поэтому иногда нажимать кнопку обновления браузера и входить в адресную строку, чтобы увидеть совершенно разные результаты в сетевом модуле
Истекает
Срок действия истечения не рекомендуется, он определяет определенную дату истечения срока действия, а не несколько секунд. Поскольку у многих серверов и клиентов есть часы, противоречивые, лучше всего использовать контроль от кэша.
Проверка сервера
Срок действия кэшированного ресурса в браузере или прокси -кэше истекает, не означает, что он на самом деле отличается от ресурсов на исходном сервере, но только означает, что пришло время проверить. Эта ситуация называется переверительностью сервера.
Если ресурс изменяется, вам необходимо получить новые ресурсы и заменить старые ресурсы в кэше.
Если ресурс не изменился, кэш должен получить только новый заголовок ответа и новое время истечения срока действия для обновления времени истечения срока действия ресурса в кэше.
Рекомендуемый метод проверки для http1.1-это if-none-match/etag, а в HTTP1.0 используется IF-модифицированный/последний модифицированный.
ETAG и IF-None Match
Сгенерировать хэш -строку на основе содержимого объекта, определение состояния ресурса и генерируется сервером. Браузер передаст эту строку обратно на сервер, чтобы убедиться, что ресурс был изменен. Если он не был изменен, процесс заключается в следующем (картина происходит от краткого обсуждения веб -кэша):
В приведенной выше демонстрации мы видели, как проверить ETAG на сервере:
Поскольку ETAG имеет структуру сервера, уникальность ETAG должна быть обеспечена в среде кластера
IF-модифицированный-синсхесс против последних модифицированных
Эти два - заголовки запроса/ответа, используемые в HTTP 1.0, чтобы проверить, истек ли ресурс. Эти два заголовка - даты. Процесс проверки похож на ETAG, поэтому мы не будем введены здесь подробно. При использовании этих двух заголовков, чтобы убедиться, что ресурс обновляется, существуют следующие проблемы:
Некоторые ресурсы документов периодически переписаны, но фактический контент не менялся. В настоящее время метаданные файла покажут, что последняя дата изменения файла отличается от модифицированной IF-модифицированной, что приводит к ненужным ответам.
Некоторые ресурсы документов были изменены, но содержание модификации не важно, и все кэши не обязаны обновлять (например, комментарии кода)
Что касается обновления кэша, пожалуйста, ознакомьтесь с ответом Чжана Юнлонга здесь. Эта статья не будет расширена подробно.
Демо -код в этой статье выглядит следующим образом:
<! Doctype html> <html> <head> <meta http-equiv = "content-type" content = "text /html; charset = utf-8"> <meta name = "viewport" content = "width = device-width, начальная масштаба = 1.0, максимальная масштаба = 1.0, пользовательский сборы = no" /> <meta = 1.0, максимальная масштаба = 1.0, пользовательский http-equiv = "x-ua-совместимый" content = "ie = edge"/> <title> веб-кэш </title> <link rel = "Значок сочетания" href = "./ shortcut.png"> <script> </script> </head> <body> <img src = ". require ('http'); var fs = require ('fs'); http.createserver (function (req, res) {if (req.url === '/' || req.url === '' || req.url === '/index.html') {fs. Консоль === '/shortcut.png') {fs.readfile ('./ shotcut.png', function (err, file) {console.log (req.url) res.setheader ('content-type', 'images/png'); res.writehead ('200', "ok"); '/cache.png') {fs.readfile ('./ cache.png', function (err, file) {console.log (req.headers); console.log (req.url) if (! req.Headers ['if-none match']) {res.setheader ('cache-control', "max-vate =" + 5); res.setheader ('content-type', 'Images/png'); res.end (); }}). Слушай (8888)Хорошо, введение в эту статью в файлы cookie заканчивается здесь, я надеюсь, что всем понравится.