쿠키의 탄생
HTTP 프로토콜은 상태가 없으므로 서버 측 서비스는 상태가 있어야합니다. 쿠키 탄생의 원래 목적은 서버 측에서 쉽게 사용하기 위해 웹에 상태 정보를 저장하는 것이 었습니다. 예를 들어, 사용자가 처음으로 웹 사이트를 방문하는지 여부를 결정하십시오. 최신 사양은 RFC 6265이며 브라우저 서버에서 구현 한 사양입니다.
쿠키 가공은 다음과 같이 나뉩니다.
서버는 클라이언트와 같은 쿠키를 보냅니다
브라우저는 쿠키를 저장합니다
그 후, HTTP 요청이 요청 될 때마다 브라우저는 쿠키를 서버로 보냅니다.
서버 측면에서 보내고 구문 분석합니다
쿠키를 보내십시오
클라이언트가 전송하는 서버 측 쿠키는 HTTP 응답 패킷을 통해 구현됩니다. 세트 쿠키에서는 클라이언트가 전송 해야하는 쿠키가 설정됩니다. 쿠키 형식은 다음과 같습니다.
set-cookie : "name = value; domain = .domain.com; path =/; Expires = sat, 11 월 11 일 11:29:42 GMT; httponly; Secure"
여기서 이름 = 값은 필수 옵션이고 다른 옵션은 선택 사항입니다. 쿠키의 주요 구성 요소는 다음과 같습니다.
이름 : 독특하고 명확한 쿠키 이름. 일반적으로 쿠키의 이름은 대소 문자를 사용하지 않습니다.
값 : 쿠키에 저장된 문자열 값. 쿠키의 이름과 가치를 인코딩하는 것이 가장 좋습니다.
도메인 : 쿠키는 어떤 도메인에 유효합니다. 이 도메인에 전송 된 모든 요청에는이 쿠키 정보가 포함됩니다. 이 값은 하위 도메인을 포함 할 수 있습니다 (예 :
yq.aliyun.com) 또는 포함 할 수 없음 (예 : .aliyun.com은 aliyun.com의 모든 하위 도메인에 유효합니다).
경로 :이 쿠키의 영향을받는 경로를 나타냅니다. 브라우저는 지정된 도메인에서 일치하는 경로와 같은이 구성에 따라 쿠키를 보냅니다.
만료 : 만료 시간, 쿠키를 삭제 해야하는시기를 나타내는 타임 스탬프 (즉, 쿠키가 서버로 전송을 중지 해야하는 경우). 이 타임 스탬프를 설정하지 않으면 페이지가 닫히면 브라우저가 모든 쿠키를 삭제합니다. 그러나 삭제 시간을 직접 설정할 수도 있습니다. 이 값은 GMT 시간 형식입니다. 클라이언트와 서버 시간이 일치하지 않으면 만료를 사용할 때 편차가 발생합니다.
MAX-AGE : 만료와 동일한 기능은 브라우저에 고정 된 시점이 아닌이 쿠키가 만료되는 시간 (초)을 알려줍니다. 정상적인 상황에서 최대 연령은 만료보다 우선 순위가 높습니다.
httponly : 브라우저에 스크립트 문서를 허용하지 않도록 알려줍니다 .Cookie는이 값을 변경하도록 하며이 값은 Document.Cookie에서도 표시되지 않습니다. 그러나이 쿠키는 여전히 HTTP 요청으로 수행됩니다. 이 값은 스크립트에서 사용할 수 없지만 브라우저 설치 디렉토리에 파일로 여전히 존재합니다. 이 설정은 일반적으로 서버 측에 설정됩니다.
Security : 보안 플래그는 지정된 후 SSL 링크를 사용할 때만 서버로만 보낼 수 있습니다. HTTP 링크 인 경우이 정보는 전달되지 않습니다. 보안 속성이 설정되어 있더라도 다른 사람들이 컴퓨터에 로컬로 저장된 쿠키 정보를 볼 수 없다는 것을 의미하지 않으므로 중요한 정보를 쿠키에 넣고 서버 측에 바로 설정하지 마십시오.
쿠키의 예는 다음과 같습니다.
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.com; res. hell World ');세트 쿠키를 직접 설정하는 것은 너무 독창적입니다. 다음과 같이 쿠키 설정 프로세스를 캡슐화 할 수 있습니다.
var serilize = function (name, val, 옵션) {if (! name) {Throw new Error ( "Cooleie는 이름이 있어야합니다"); } var Enc = encodeUricomponent; var parts = []; val = (val! == null && val! == 정의되지 않은)? val.toString () : ""; 옵션 = 옵션 || {}; parts.push (enc (name) + "=" + enc (val)); // 도메인에 두 개의 점이 있어야한다면 (옵션 .Domain) {parts.push ( "domain =" + 옵션 .Domain); } if (Options.Path) {parts.push ( "path =" + 옵션.Path); } // 만료를 설정하지 않으면 (옵션.expires) {parts.push ( "expires =" + 옵션.expires.togmtstring ()); } if (옵션 .maxage && typeof 옵션. } if (Options.httponly) {parts.push ( "httponly"); } if (Options.Secure) {parts.push ( "secure"); } return parts.join ( ";");}쿠키가 지난 시간으로 설정되면 브라우저는 즉시 쿠키를 삭제합니다. 또한 도메인 항목에는 두 점이 있어야하므로 LocalHost로 설정할 수 없습니다.
여기서 나에게 명확하지 않은 것은 도메인 이름이 적어도 두 개의 점 () 이상을 포함해야한다는 것이었기 때문에 'LocalHost'는 유효하지 않으며 브라우저는 쿠키를 설정하지 않을 것입니다.
서버 측 분석 쿠키
쿠키는 다른 도메인과 경로를 설정할 수 있으므로 동일한 이름 값의 경우 다른 도메인과 다른 경로에서 다른 경로에서 반복 할 수 있습니다. 브라우저는 현재 요청 된 URL 또는 페이지 주소와 가장 일치하는 순서대로 순서를 정렬합니다.
따라서 쿠키가 현재 측면의 서버쪽으로 전달되면 여러 개의 중복 이름 값이 있습니다. 가장 일치하는 것, 즉 첫 번째 이름 만 필요합니다. 서버 측 파싱 코드는 다음과 같습니다.
var parse = function (cstr) {if (! cstr) {return null; } var dec = decodeUricomponent; var 쿠키 = {}; var parts = cstr.split (// s*;/s*/g); parts.foreach (function (p) {var pos = p.indexof ( '='); // 이름과 값은 쿠키가 저장되기 전에 var name = pos> -1? dec (p.substr (0, pos)) : p; var val = pos> -1? dec (p.substr (pos + 1)) : null; 쿠키 [name]}/* else (! 쿠키 인스턴스) {쿠키 [name]. 쿠키 반환;}클라이언트 액세스
브라우저는 백그라운드에서 전달 된 쿠키를 관리하고 개발자가 쿠키에 액세스하기 위해 javaScript의 문서를 사용할 수 있도록합니다. 그러나이 인터페이스는 사용하기가 매우 절름발이입니다. 사용되는 방식으로 인해 다른 행동을 보여줍니다.
속성 값을 얻는 데 사용되는 경우, 문서 .Cookie는 현재 페이지에서 사용 가능한 모든 문자열을 반환합니다 (쿠키 도메인, 경로, 만료 시간 및 보안 설정에 따라). 문자열의 형식은 다음과 같습니다.
"name1 = value1; name2 = value2; name3 = value3";
값을 설정하는 데 사용될 때 문서 .cookie 속성을 새 쿠키 문자열로 설정할 수 있습니다. 이 문자열은 기존 쿠키 컬렉션을 해석하고 추가합니다. 좋다:
document.cookie = "_fa = aaaffffasdsf; domain = .dojotoolkit.org; path =/"
Seting Name Value 도메인 경로가 기존 쿠키로 반복되지 않는 한 쿠키를 재정의하지 않습니다.
쿠키를 읽고 쓰는 것이 매우 불편하기 때문에 쿠키의 추가, 수정 및 삭제를 위해 쿠키를 처리하기 위해 일부 기능을 캡슐화 할 수 있습니다.
var cookieutils = {get : function (name) {var cookiename = encodeUricomponent (name) + "="; // 가장 일치하는 이름 만 얻을 수 있습니다. var cookievalue = null; if (cookiestart> -1) {// cookiestart var 쿠키 엔드 = document.cookie.indexof ( ';', CookiestArt); // from = (쿠키 엔드> -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, 옵션) {if (! name) {strash new error ( "cooliie는 이름이 있어야합니다"); } var Enc = encodeUricomponent; var parts = []; val = (val! == null && val! == 정의되지 않은)? val.toString () : ""; 옵션 = 옵션 || {}; parts.push (enc (name) + "=" + enc (val)); // 도메인에는 if (옵션 .Domain) {parts.push ( "domain =" + 옵션 .Domain); } if (Options.Path) {parts.push ( "path =" + 옵션.Path); } // 만료를 설정하지 않고 최대 시대 브라우저가 페이지를 닫을 때 쿠키를 지 웁니다. } // 만료를 설정하지 않고 최대 시대 브라우저가 페이지를 닫을 때 쿠키를 지 웁니다. (옵션 .expires) {parts.push ( "expires =" + 옵션.expires.togmtstring ()); } if (옵션 .maxage && typeof 옵션. } if (Options.httponly) {parts.push ( "httponly"); } if (Options.Secure) {parts.push ( "secure"); } document.cookie = parts.join ( ";"); }, delete : function (이름, 옵션) {옵션 .expires = 새 날짜 (0); // 과거 날짜로 설정 this.set (이름, null, 옵션); }}캐싱의 장점
일반적으로 웹 캐시라고하는 것은 일반적인 HTTP 요청 사본을 자동으로 저장할 수있는 HTTP 장치를 나타냅니다. 프론트 엔드 개발자에게는 브라우저가 중요한 역할을합니다. 또한 캐싱에도 사용할 수있는 다양한 공통 프록시 서버가 있습니다. 웹 요청이 캐시에 도달하면 캐시는 서버를 통과하지 않고 로컬 복제본에서 복제 내용을 추출합니다. 이것은 다음과 같은 장점을 제공합니다.
캐싱은 중복 데이터 전송을 줄이고 트래픽을 저장합니다
캐시는 대역폭 병목 현상 문제를 완화시킵니다. 더 많은 대역폭없이 페이지를 더 빨리로드 할 수 있습니다
캐시는 인스턴트 혼잡을 완화하고 원래 서버의 요구 사항을 줄입니다.
캐시는 더 먼 곳에서 페이지를로드하는 것이 느리기 때문에 거리 지연을 줄입니다.
캐시 유형
캐시는 단일 사용자에게 전용되거나 여러 사용자가 공유 할 수 있습니다. 전용 캐시를 개인 캐시라고하며 공유 캐시를 공개 캐시라고합니다.
개인 캐시
개인 캐시는 독점 사용자만을위한 것이므로 많은 공간이 필요하지 않으며 저렴합니다. 웹 브라우저에는 개인 캐시가 내장되어 있습니다. 대부분의 브라우저는 PC의 디스크 및 메모리에서 공통 리소스를 캐시합니다. 예를 들어, 크롬 브라우저의 캐시 저장 위치는 다음과 같습니다.
공개 캐시
공개 캐시는 캐시 프록시 서버 또는 프록시 캐시 (리버스 프록시 목적)라고하는 특수 공유 프록시 서버입니다. 공개 캐시는 여러 사용자의 액세스를 허용하므로 중복 트래픽을 더 잘 줄일 수 있습니다.
아래 그림에서 각 클라이언트는 서버에 대한 리소스에 반복적으로 액세스하여 (현재 개인 캐시에 있지 않음) 서버에 여러 번 액세스하여 서버의 압력을 증가시킵니다. 공유 공개 캐시를 사용하는 경우 캐시는 서버에서 한 번만 검색되면 앞으로 서버를 통과 할 필요가 없으므로 서버의 압력을 크게 줄일 수 있습니다.
실제로, 계층 적 공개 캐시는 일반적으로 실제 애플리케이션에 사용됩니다. 기본 아이디어는 클라이언트 근처에 작고 저렴한 캐시를 사용하는 것이며, 더 높은 수준에서는 더 크고 강력한 캐시가 여러 사용자가 공유하는 리소스를로드하기 위해 점차 채택됩니다.
캐시 처리 흐름
프론트 엔드 개발자의 경우 주로 브라우저의 캐시를 다루므로 위의 프로세스가 단순화됩니다.
다음 그림은 다양한 리소스에 대한 웹 사이트의 요청 결과를 보여줍니다. 일부 리소스는 캐시에서 직접 읽히고 일부 리소스는 서버와 함께 재확인되며 일부 리소스는 서버에서 다시 인쇄됩니다.
캐시 리소스에 대해 논의한 모든 질문은 GET 요청에만 해당됩니다. Post, Delete 및 Put과 같은 행동 작업의 경우 일반적으로 캐시가 없습니다.
신선도 한도
HTTP는 캐시를 통해 일정 기간 동안 서버 리소스의 사본을 보유합니다. 이것은 일정 기간 동안 동일한 리소스를 요청하며 다시 서버를 통과하지 않습니다. HTTP 프로토콜에서 캐시 제어 및 만료는 신선도 한계를 설정하는 데 사용될 수 있습니다. 전자는 HTTP1.1에 추가 된 새로운 응답 헤더이고 후자는 HTTP1.0의 응답 헤더입니다. 둘 다 동일한 작업을 수행하지만 캐시 제어는 상대 시간을 사용하고 만료되면 클라이언트와 서버 시간이 다르다는 문제가 발생할 수 있으므로 캐시 제어를 선호합니다.
캐시 제어
Cache-Control에서 어떤 속성 값을 설정할 수 있는지 살펴 보겠습니다.
MAX-AGE (단위 IS)는 캐시를 설정하는 최대 유효한 시간을 지정하여 시간을 정의합니다. 브라우저가 요청을 서버로 보낼 때 브라우저는 더 이상 최대 연령 동안 서버에 요청을 보내지 않습니다.
<html> <head> <meta http-equiv = "content-type"content = "text /html; charset = utf-8"> <meta name = "viewport"content = "width = device-width, device-width, maximum-scale = 1.0, user-scalable = no" /> <meta http-equiv = "x-u-compative" content = "ee = edge"/> <title> 웹 캐시 </title> <link rel = "바로 가기 아이콘"href = "./ smart.png"> <cript> </script> </head> <body> <img src = "./ cache.png"> </body> </html> var http = 요구 (http '); reque ( 'fs'); http.createserver (function (req, res) {if (req.url === '/'|| req.url === ''|| req.url === '/index.html') {fs.readfile ( './ index.html', function (err, req.) 메인 문서, '캐시 제어', "Conte-Type ','Text/HTML '; fs.readfile ( './ cache.png', function (err, file) {res.setheader ( 'cache-control', "max-age =" + 5); // 5 초 res.setheader ( 'content-type', 'images/png'); res.writehead ( '200'); }). 듣기 (8888)페이지가 5 초 이내에 두 번째로 액세스되면 브라우저는 캐시에서 직접 리소스를 얻습니다.
Public은 프록시 캐시에 응답을 캐시 할 수 있으므로 여러 사용자가 공유 할 수 있다고 지정합니다. 개인이 명시 적으로 지정되지 않은 경우 기본값은 공개됩니다.
개인 응답은 개인 캐시에만 캐시 될 수 있으며 프록시 캐시에 배치 할 수 없습니다. 일부 사용자 정보에 민감한 리소스는 일반적으로 비공개로 설정해야합니다.
캐시가 없다는 것은 로컬 캐시 사용 여부를 결정하기 전에 리소스가 변경되었는지 여부 (비 일치 및 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); 'ETAG', 'FFFF'; Res.Setheader (Cache-Control ', " + 5);매장은 모든 리소스의 캐시를 절대적으로 금지하는데, 이는 사용자가 리소스를 요청할 때마다 요청이 서버로 전송되며 전체 리소스가 매번 다운로드됩니다. 일반적으로 기밀 리소스에 사용됩니다.
캐시 제어 사용과 관련하여 아래 그림을 참조하십시오 (많은 양에서)
클라이언트 신선도 한도
캐시 제어는 응답 헤더뿐만 아니라 요청 헤더에도 설정할 수 있습니다. 브라우저는 요청 헤더에서 캐시 제어를 설정하여 캐시에서 리소스를 읽을지 여부를 결정할 수 있습니다. 또한 브라우저 새로 고침 버튼을 클릭하고 주소 표시 줄에 입력하여 네트워크 모듈에서 완전히 다른 결과를 볼 수있는 이유도 있습니다.
만료
만료는 권장되지 않으며, 몇 초가 아닌 특정 만료 날짜를 지정합니다. 많은 서버와 클라이언트가 시계가 일관되지 않기 때문에 캐시 제어를 사용하는 것이 가장 좋습니다.
서버 검증
브라우저 또는 프록시 캐시의 캐시 된 리소스는 만료 된 것이 원래 서버의 리소스와 실제로 다르다는 것을 의미하지는 않지만 확인해야 할 시간입니다. 이 상황을 서버 회전이라고합니다.
자원이 변경되면 새로운 리소스를 얻고 캐시의 기존 자원을 교체해야합니다.
리소스가 변경되지 않은 경우 캐시는 캐시에서 리소스의 만료 시간을 업데이트하기 위해 새로운 응답 헤더와 새로운 만료 시간 만 얻어야합니다.
HTTP1.1에 대한 권장 확인 방법은 IF-None-Match/Etag이며, IF 모형화 된 Since/Last Modified는 HTTP1.0에서 사용됩니다.
에 태그 및 if-none-match
엔티티 컨텐츠를 기반으로 해시 문자열을 생성하고 리소스의 상태를 식별하고 서버에서 생성합니다. 브라우저는이 문자열을 서버로 다시 전달하여 리소스가 수정되었는지 확인합니다. 수정되지 않은 경우 프로세스는 다음과 같습니다 (사진은 웹 캐시에 대한 간단한 토론에서 나온다).
위의 데모에서 서버에서 ETAG를 확인하는 방법을 보았습니다.
ETAG에는 서버 구조가 있으므로 클러스터 환경에서 ETAG의 고유성이 보장되어야합니다.
if-modified-since vs. 최후의 수정
이 두 가지는 자원이 만료되었는지 확인하기 위해 HTTP 1.0에 사용되는 요청/응답 헤더입니다. 이 두 헤더는 날짜입니다. 검증 프로세스는 ETAG와 유사하므로 여기에서 자세히 소개하지 않습니다. 이 두 헤더를 사용하여 리소스가 업데이트되었는지 확인할 때 다음과 같은 문제가 있습니다.
일부 문서 리소스는 주기적으로 다시 작성되지만 실제 콘텐츠는 변경되지 않았습니다. 이 시점에서 파일 메타 데이터는 파일의 최신 수정 날짜가 if-modified-since와 다르기 때문에 불필요한 응답을 보여줍니다.
일부 문서 리소스가 수정되었지만 수정의 내용은 중요하지 않으며 모든 캐시를 업데이트 할 필요는 없습니다 (예 : 코드 주석).
캐시 업데이트와 관련하여 Zhang Yunlong의 답변을 확인하십시오. 이 기사는 자세히 확장되지 않습니다.
이 기사의 데모 코드는 다음과 같습니다.
<! docType html> <html> <head> <meta http-equiv = "content-type"content = "text /html; charset = utf-8"> <meta name = "viewport"content = "width = device-width, device-width = meta < /> <meta" />>>>>>. http-equiv = "x-ua-catsible"content = "ie = edge"/> <title> web cache </title> <link rel = "바로 가기 아이콘"href = "./ shref.png"> <cript> </script> </head> <body> <img src = "./ cache.png"> </html> </html> reque ( 'http'); var fs = require ( 'fs'); http.createserver (function (req, res) {if (req.url === '/'|| req.url === ''|| req.url === '/index.html') {fs.Readfile ( './ eRREDML', function (erry), function (eRREDML ', function). Console.log (req.url)는 메인 문서에 대한 캐시를 설정합니다 '/shortcut.png') {fs.readfile ( './ shortcut.png', function (err, file) {console.log (req.url) res.setheader ( 'content-type', 'images/png'); res.writehead ( '200', "ok"); res.end (res.end); '/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-5 5); res.setheader ( 'etag', 'ffff ") ('etag ','res.end '; res.ender {Cache-Control ', "res.setheader (indage-type/png'); }}). 듣기 (8888)좋아,이 기사의 쿠키 소개는 여기서 끝납니다. 모두가 좋아하기를 바랍니다.