Die Geburt von Keksen
Da das HTTP-Protokoll staatenlos ist, müssen die serverseitigen Dienste staatlich sein. Der ursprüngliche Zweck der Geburt von Cookies bestand darin, Statusinformationen im Web zu speichern, um auf der Serverseite eine einfache Verwendung zu erhalten. Stellen Sie beispielsweise fest, ob der Benutzer die Website zum ersten Mal besucht. Die neueste Spezifikation ist RFC 6265, eine Spezifikation, die von Browser -Servern implementiert wird.
Die Verarbeitung von Cookies ist unterteilt in:
Server sendet Cookies wie Client
Der Browser spart Cookies
Danach sendet der Browser jedes Mal, wenn die HTTP -Anfrage angefordert wird, den Cookie an den Server.
Senden und analysieren auf der Serverseite
Senden Sie Cookies
Die vom Client gesendeten serverseitigen Cookies werden über HTTP-Antwortpakete implementiert. In Set-Cookies werden Cookies, die vom Client gesendet werden müssen, festgelegt. Das Cookie -Format lautet wie folgt:
Set-Cookie: "name = value; domain = .domain.com; path =/; ablehnt = SAT, 11. Juni 2016 11:29:42 GMT; httponly; sicher"
Wobei Name = Wert eine erforderliche Option ist und andere optional sind. Die Hauptkomponenten von Cookies sind wie folgt:
Name: Ein eindeutiger und eindeutiger Keksname. Im Allgemeinen ist der Name eines Keks mit Fall unempfindlich.
Wert: Der im Cookie gespeicherte Stringwert. Es ist am besten, den Namen und den Wert des Keks zu kodieren
Domain: Cookie gilt für welche Domain. Alle an diese Domain gesendeten Anfragen enthalten diese Cookie -Informationen. Dieser Wert kann Subdomains enthalten (z. B.:
yq.aliyun.com) oder es kann nicht enthalten sein (z. B. .aliyun.com, es gilt für alle Subdomains von Aliyun.com).
Pfad: Zeigt den von diesem Keks betroffenen Pfad an. Der Browser sendet Cookies basierend auf dieser Konfiguration, z. B. dem Pfadabgleich in der angegebenen Domäne.
Ausgelassen: Ablaufzeit, Zeitstempel, der angibt, wann der Cookie gelöscht werden sollte (dh, wann der Cookie auf den Server eingestellt werden sollte). Wenn Sie diesen Zeitstempel nicht festlegen, löscht der Browser alle Cookies, wenn die Seite geschlossen ist. Sie können jedoch auch die Löschzeit selbst festlegen. Dieser Wert befindet sich im GMT -Zeitformat. Wenn die Client- und Serverzeit inkonsistent ist, gibt es Abweichungen, wenn es abläuft.
max-alte: Die gleiche Funktion wie abläuft, wird verwendet, um dem Browser zu mitteilen, wie lange dieser Keks (in Sekunden) und nicht zu einem festen Zeitpunkt aussieht. Unter normalen Umständen hat maximales Alter eine höhere Priorität als abläuft.
Httponly: informiert den Browser, das Skriptdokument nicht zu erlauben. Kookie kann diesen Wert ändern, und dieser Wert ist auch in document.cookie nicht sichtbar. Dieser Keks wird jedoch weiterhin auf eine HTTP -Anfrage übertragen. Beachten Sie, dass dieser Wert zwar nicht im Skript verfügbar ist, er jedoch im Browser -Installationsverzeichnis als Datei weiterhin vorhanden ist. Diese Einstellung wird normalerweise auf der Serverseite festgelegt.
Sicher: Sicherheitsflag, nach Angabe kann es nur bei Verwendung von SSL -Link an den Server gesendet werden. Wenn es sich um einen HTTP -Link handelt, werden diese Informationen nicht übergeben. Auch wenn das sichere Attribut festgelegt ist, bedeutet dies nicht, dass andere die Cookie -Informationen, die lokal auf Ihrem Computer gespeichert sind, nicht sehen können. Geben Sie also keine wichtigen Informationen in Cookies ein und stellen Sie sie direkt auf der Serverseite ein.
Beispiele für Kekse sind wie folgt:
var http = required ('http'); var fs = require ('fs'); Welt ');Das direkte Einstellen von Set-Cookie ist zu originell. Wir können den Cookie -Einstellungsvorgang wie folgt zusammenfassen:
var serilize = function (name, val, options) {if (! name) {wurf neuer error ("Coolei muss Name haben"); } var Enc = Encodeuricomponent; var parts = []; val = (val! == null && val! == undefiniert)? Val.ToString (): ""; Optionen = Optionen || {}; Teils.push (Enc (Name) + "=" + Enc (Val)); // Es müssen zwei Punkte in der Domäne sein, wenn (options.domain) {parts.push ("Domain =" + options.domain); } if (options.Path) {parts.push ("path =" + options.path); } // Wenn Sie nicht abgelaufen sind und Max-Alter-Browser Cookies löschen, wenn die Seite geschlossen ist, wenn (options.expires) {parts.push ("expires =" + options.expires.togmtstring ())); } if (options.maxage && typeof options } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("sichere"); } return parts.join (";");}Es ist zu beachten, dass der Browser den Cookie sofort löscht, wenn ein Cookie auf eine vergangene Zeit eingestellt ist. Darüber hinaus muss das Domänenelement zwei Punkte haben, sodass es nicht auf Localhost festgelegt werden kann:
Etwas, das mir hier nicht klar machte und mich für eine Weile völlig verwirrte, war, dass Domain -Namen mindestens zwei Punkte () enthalten mussten, daher ist 'localhost' ungültig und der Browser wehte es ab, den Keks einzustellen!
Serverseitige Analyse Cookies
Cookies können verschiedene Domänen und Pfade festlegen, sodass es für denselben Namenswert unter verschiedenen Pfaden in verschiedenen Domänen und unterschiedlichen Pfaden wiederholt werden kann. Der Browser sortiert die Reihenfolge in der Reihenfolge, die am besten mit der aktuellen angeforderten URL- oder Seitenadresse entspricht.
Wenn also das Cookie auf der aktuellen Seite an die Serverseite übergeben wird, benötigen wir nur diejenigen, die am meisten übereinstimmt, dh die erste. Der serverseitige Parsencode lautet wie folgt:
var parse = function (cstr) {if (! cstr) {return null; } var dec = decodeuricomponent; var cookies = {}; var parts = cstr.split (// s*;/s*/g); parts.foreach (Funktion (p) {var pos = p.indexof ('='); // Name und Wert muss codiert werden, bevor der Cookie gespeichert ist var name = pos> -1? dec (p.Substr (0, pos)): p; var val = pos> -1? dec (p.Substr (pos + 1): Null; // // nur du musst das meiste Matching, wenn du das meiste Matching erwerben musst, wenn du das meiste Mal erreichst. cookies [name] = val; Kekse zurückgeben;}Kundenzugriff
Der Browser verwaltet Cookies, die im Hintergrund übergeben wurden, und ermöglicht es Entwicklern, Dokument.kochen in JavaScript zum Zugriff auf Cookies zu verwenden. Diese Schnittstelle ist jedoch sehr lahm zu bedienen. Es zeigt verschiedene Verhaltensweisen aufgrund der unterschiedlichen Möglichkeiten, wie es verwendet wird.
Bei Verwendung von Attributwerten wird document.cookie alle auf der aktuellen Seite verfügbaren Zeichenfolgen zurückgegeben (basierend auf der Domäne, Pfad, Ablaufzeit und Sicherheitseinstellungen des Cookies). Das Format der Zeichenfolge lautet wie folgt:
"name1 = value1; name2 = value2; name3 = value3";
Bei Verwendung zum Festlegen von Werten kann die Eigenschaft document.cookie auf eine neue Cookie -Zeichenfolge eingestellt werden. Diese Zeichenfolge wird interpretiert und zur vorhandenen Cookie -Sammlung hinzugefügt. wie:
document.cookie = "_fa = aaaffffasdsf; domain = .dojotoolkit.org; path =/"
Einstellungsdokument.Cookie überschreibt keine Cookies, es sei denn, der festgelegte Pfad für den Namen Value Domain wird mit einem vorhandenen Cookie wiederholt.
Da es sehr unpraktisch ist, Cookies zu lesen und zu schreiben, können wir einige Funktionen zusammenfassen, um Cookies zu verarbeiten, hauptsächlich für die Hinzufügung, Änderung und Löschung von Cookies.
var CookiEUTILS = {get: function (name) {var cookiename = ccodeuricomponent (name) + "="; // Erhalten Sie nur den passendsten Namen, Value var cookiestart = document.cookie.indexof (Cookiename); var cookievalue = null; if (cookiestart> -1) {// von cookiestart var cookieend = document.cookie.indexof (';', cookiestart); // von = After = (Cookieend> -1) {cookievalue = decodeuricomponent (document.cookie.substring (cookiestart + cookiename.length, Cookieend)); } else {cookievalue = decodeuricomponent (document.cookie.substring (cookiestart + cookiename.length, document.cookie.length)); }} return Cookievalue; }, set: function (name, val, option) {if (! name) {neue error werfen ("cooliie muss name haben"); } var Enc = Encodeuricomponent; var parts = []; val = (val! == null && val! == undefiniert)? Val.ToString (): ""; Optionen = Optionen || {}; Teils.push (Enc (Name) + "=" + Enc (Val)); // Die Domäne muss zwei Punkte enthalten, wenn (option.domain) {parts.push ("Domain =" + options.domain); } if (options.Path) {parts.push ("path =" + options.path); } // Wenn Sie nicht abgelaufen sind und der Max-Alter-Browser Cookies löscht, wenn die Seite geschlossen ist, wenn (options.expires) {parts.push ("expires =" + options.path); } // Wenn Sie nicht abgelaufen sind und der Max-Alter-Browser Cookies löscht, wenn die Seite geschlossen ist, wenn (options.expires) {parts.push ("expires =" + options.expires.togmtstring ())); } if (options.maxage && typeof options } if (options.httponly) {parts.push ("httponly"); } if (options.secure) {parts.push ("sichere"); } document.cookie = parts.join (";"); }, löschen: Funktion (Name, Optionen) {options.expires = neues Datum (0); // auf vergangene Datum dieses.set (Name, Null, Optionen) festgelegt; }}Vorteile des Caching
Der allgemein als Web -Cache bezeichnete Cache bezieht sich auf ein HTTP -Gerät, mit dem automatisch Kopien von gängigen HTTP -Anforderungen speichern können. Für Front-End-Entwickler spielen Browser eine wichtige Rolle. Darüber hinaus gibt es verschiedene gängige Proxy -Server, die auch zum Caching verwendet werden können. Wenn eine Webanforderung den Cache erreicht, extrahiert der Cache den Replikatinhalt aus der lokalen Replikat ohne den Server. Dies bringt die folgenden Vorteile mit sich:
Das Caching reduziert die redundante Datenübertragung und spart den Verkehr
Cache lindert die Probleme mit der Bandbreite von Bandbreiten. Seiten können ohne mehr Bandbreite schneller geladen werden
Der Cache lindert sofortige Überlastung und verringert die Anforderungen für den ursprünglichen Server.
Der Cache reduziert die Entfernungsverzögerung, da das Ladungsseiten von weiteren Stellen langsamer werden.
Cache -Typ
Der Cache kann einem einzelnen Benutzer gewidmet sein oder von mehreren Benutzern gemeinsam genutzt werden. Ein dedizierter Cache wird als privater Cache bezeichnet, und ein gemeinsamer Cache wird als öffentlicher Cache bezeichnet.
Privatcache
Private Cache ist nur für proprietäre Benutzer gedacht, daher erfordert es nicht viel Platz und ist billig. Webbrowser verfügen über integrierte private Caches - die meisten Browser werden gemeinsame Ressourcen auf der Festplatte und dem Speicher Ihres PCs unterbinden. Der Cache -Speicherort des Chrome -Browsers lautet beispielsweise: c:/user/your_account/appdata/local/google/Chrome/Benutzerdaten/Standard.
Öffentlicher Cache
Öffentliche Caches sind spezielle gemeinsame Proxy -Server, die Cache -Proxy -Server oder Proxy -Caches (ein Zweck von Reverse Proxy) genannt werden. Der öffentliche Cache akzeptiert den Zugriff von mehreren Benutzern, sodass der redundante Verkehr besser reduzieren kann.
In der folgenden Abbildung greifen jeder Client wiederholt auf eine Ressource auf den Server zu (er befindet sich zu diesem Zeitpunkt nicht im privaten Cache), sodass er mehrmals auf den Server zugreift und den Druck auf den Server erhöht. Bei der Verwendung eines gemeinsam genutzten öffentlichen Cache muss der Cache nur einmal vom Server abgerufen werden und muss den Server in Zukunft nicht übergeben, was den Druck auf den Server erheblich verringern kann.
In der Tat wird hierarchischer öffentlicher Cache in tatsächlichen Anwendungen normalerweise verwendet. Die Grundidee besteht darin, kleine und billige Caches in der Nähe des Kunden zu verwenden, während auf einer höheren Ebene größere und leistungsfähigere Caches nach und nach angewendet werden, um Ressourcen zu laden, die von mehreren Benutzern gemeinsam genutzt werden.
Cache -Verarbeitungsfluss
Für Front-End-Entwickler beschäftigen wir uns hauptsächlich mit Caches im Browser, sodass der obige Vorgang vereinfacht wird:
Das folgende Bild zeigt die Anfrageergebnisse einer Website für verschiedene Ressourcen. Es ist ersichtlich, dass einige Ressourcen direkt aus dem Cache gelesen werden, einige Ressourcen mit dem Server verehrt werden und einige Ressourcen vom Server wieder aufgenommen werden.
Beachten Sie, dass alle Fragen, die wir zu Cache -Ressourcen besprochen haben, nur für Get -Anfragen gelten. Für Verhaltensvorgänge wie Post, Löschen und Aussagen gibt es normalerweise keinen Cache.
Frische Grenze
HTTP behält eine Kopie der Serverressource für einen bestimmten Zeitraum über Cache bei, was als Frischlimit bezeichnet wird. Dies fordert dieselbe Ressource für einen bestimmten Zeitraum und wird den Server nicht erneut durchlaufen. Cache-Control und Auslauf im HTTP-Protokoll können verwendet werden, um die Frischegrenze festzulegen. Ersteres ist der neue Response -Header, der in http1.1 hinzugefügt wurde, und letzteres ist der Antwortheader in http1.0. Beide tun das Gleiche, aber da Cache-Control die relative Zeit nutzt und Ablauf möglicherweise ein Problem hat, dass die Client- und Serverzeit unterschiedlich ist, bevorzugen wir Cache-Control.
Cache-Kontroll
Schauen wir uns an, welche Attributwerte durch Cache-Control festgelegt werden können:
Maximal (Einheit ist s) legt die maximal gültige Zeit zum Festlegen des Cache an, der die Zeitdauer definiert. Wenn der Browser eine Anforderung an den Server sendet, sendet der Browser während des maximalen Alters keine Anforderung mehr an den Server.
<html> <head> <meta http-äquiv = "content-type" content = "text /html; charSet = utf-8"> <meta name = "viewport" content = "width = Geräte-Width, initial scale = 1.0, maximal-scale = 1,0, user-scalable = no" /> <meta http- content = "ie = edge"/> <title> Web -Cache </title> <link rel = "Shortcut -Symbol" href = "./ Shortcut.png"> <script> </script> </hadel> <body> <img src = "./ Cache.png"> </body> </html> var http = erfordert ('http'; required ('fs'); Cache für das Hauptdokument, res. FS. }). Hören (8888)Wenn die Seite innerhalb von 5 Sekunden zum zweiten Mal zugegriffen wird, erhält der Browser direkt Ressourcen aus dem Cache
Public gibt an, dass die Antwort im Proxy -Cache zwischengespeichert werden kann und daher von mehreren Benutzern gemeinsam genutzt werden kann. Wenn privat nicht explizit angegeben ist, wird es in der Öffentlichkeit ausfällt.
Die private Antwort kann nur im privaten Cache zwischengespeichert werden und kann nicht auf den Proxy -Cache platziert werden. Ressourcen, die für einige Benutzerinformationen sensibel sind, müssen normalerweise auf privat eingestellt werden.
No-Cache bedeutet, dass Sie zuerst mit dem Server bestätigen müssen, ob die Ressource geändert wurde (wenn Sie sich auf IF-None-Match und ETAG verlassen), bevor Sie entscheiden, ob lokale Cache verwendet werden soll.
Wenn die obige Verarbeitung von cache.png in Folgendes geändert wird, muss der Browser jedes Mal, wenn Sie die Seite besuchen, zum Server gehen, um zu überprüfen, ob die Ressource geändert wurde.
fs 'Bilder/png'); Res.
No-Store verbietet den Cache einer Ressource absolut, was bedeutet, dass jedes Mal, wenn der Benutzer die Ressource anfordert, eine Anforderung an den Server gesendet wird und die vollständige Ressource jedes Mal heruntergeladen wird. Normalerweise für vertrauliche Ressourcen verwendet.
In Bezug auf die Verwendung von Cache-Control siehe das Bild unten (aus großen Mengen)
Kundenfrische Grenze
Cache-Control kann nicht nur im Antwortheader, sondern auch im Anforderungsheader festgelegt werden. Der Browser kann entscheiden, ob Ressourcen aus dem Cache gelesen werden sollen, indem die Cache-Kontroll im Anforderungsheader festgelegt wird. Dies ist auch der Grund, warum manchmal auf die Schaltfläche "Browser -Aktualisierung" klicken und in die Adressleiste eingeben, um vollständig unterschiedliche Ergebnisse im Netzwerkmodul zu sehen
Läuft ab
Ausläufe wird nicht empfohlen, es wird eher ein bestimmtes Ablaufdatum als eine Reihe von Sekunden angegeben. Da viele Server und Clients inkonsistent die Uhr haben, ist es am besten, Cache-Control zu verwenden.
Serverüberprüfung
Die zwischengespeicherte Ressource im Browser- oder Proxy -Cache abläuft nicht, dass sie sich tatsächlich von den Ressourcen auf dem ursprünglichen Server unterscheidet, sondern nur, dass es Zeit ist, zu überprüfen. Diese Situation wird als Server-Überprüfung bezeichnet.
Wenn sich die Ressourcen ändert, müssen Sie neue Ressourcen erhalten und die alten Ressourcen im Cache ersetzen.
Wenn sich die Ressource nicht geändert hat, muss der Cache nur einen neuen Antwortheader und eine neue Ablaufzeit erhalten, um die Ablaufzeit der Ressource im Cache zu aktualisieren.
Die empfohlene Überprüfungsmethode für HTTP1.1 ist IF-None-Match/ETAG, und IF-Modified-Since/Last-Modified wird in http1.0 verwendet.
ETAG und IF-None-Match
Generieren Sie eine Hash -Zeichenfolge basierend auf dem Entitätsinhalt, wodurch der Status der Ressource identifiziert wird und vom Server generiert wird. Der Browser übergibt diese Zeichenfolge an den Server zurück, um zu überprüfen, ob die Ressource geändert wurde. Wenn es nicht geändert wurde, ist der Prozess wie folgt (das Bild stammt aus einer kurzen Diskussion über Web -Cache):
In der obigen Demo haben wir gesehen, wie ETAG auf dem Server verifiziert werden kann:
Da ETAG eine Serverstruktur hat, muss die Einzigartigkeit von ETAG in der Cluster -Umgebung sichergestellt werden
If-modifizierte Sinne im Vergleich zu Last-Modified
Diese beiden sind Anforderungs-/Antwort -Header, die in HTTP 1.0 verwendet werden, um zu überprüfen, ob die Ressource abgelaufen ist. Diese beiden Header sind Daten. Der Überprüfungsprozess ähnelt ETAG, sodass wir ihn hier nicht ausführlich einführen werden. Bei Verwendung dieser beiden Header, um zu überprüfen, ob die Ressource aktualisiert wird, gibt es folgende Probleme:
Einige Dokumentressourcen werden regelmäßig umgeschrieben, aber der tatsächliche Inhalt hat sich nicht geändert. Zu diesem Zeitpunkt zeigt die Dateimetadaten, dass sich das jüngste Änderungsdatum der Datei von if-modifizierten Since unterscheidet, was zu unnötigen Antworten führt.
Einige Dokumentressourcen wurden geändert, aber der Inhalt der Änderung ist nicht wichtig, und alle Caches müssen nicht aktualisiert werden (z. B. Code -Kommentare)
In Bezug auf das Update von Cache finden Sie hier die Antwort von Zhang Yunlong hier. Dieser Artikel wird nicht im Detail erweitert.
Der Demo -Code in diesem Artikel lautet wie folgt:
<! DocType html> <html> <head> <meta http-äquiv = "content-type" content = "text /html; charSet = utf-8"> <meta name = "AnsichtPort" content = "width = Geräte-Width, initial-scale = 1.0, maximal-scale = 1.0, user-calable http-äquiv = "x-ua-kompatible" content = "ie = edge"/> <titel> Web-Cache </title> <link rel = "Shortcut-Symbol" href = "./ Shortcut.png"> <script> required ('http'); var fs = required ('fs'); console === '/shortcut.png') {fs.ReadFile ('./ Shortcut.png', Funktion (err, file) {console.log (req.url) res.setheader ('content-type', 'Images/png') res.writeShead ('200', "OK"); '/cache.png') {fs.ReadFile ('./ Cache.png', Funktion (err, file) {console.log (req.Headers); console.log (req.url) if (! req.Headers ['if-none-match']) {res.setHeThader ('cache-control', "max-match '] + 5); Res. res.end (); }}). Hören (8888)OK, die Einführung dieses Artikels in Cookies endet hier, ich hoffe, es mag es.