附录:常用HTTP响应头和请求头信息对照表

Node简介

第一个node程序

module(模块系统)

npm包管理器

模块系统优先级

认识http内置模块

url内置模块

path内置模块

fs内置模块

http模块服务端进阶

http报文浅析

url模块进阶

path模块进阶

querystring模块进阶

了解Buffer和Stream

os模块

Buffer模块

Stream模块

http模块客户端

Cookie浅析

什么是 Cookie

Cookie 是什么,有以下几个点:

  • Cookie 就是浏览器储存在用户电脑上的一小段文本文件
  • Cookie 是纯文本格式,不包含任何可执行的代码
  • Cookie 由键值对构成,由分号和空格隔开
  • Cookie 虽然是存储在浏览器,但是通常由服务器端进行设置
  • Cookie 的大小限制在 4kb 左右

Cookie 是怎样工作的

Cookie 是如何工作的:

1. 首先,我们假设当前域名下还是没有 Cookie 的
2. 接下来,浏览器发送了一个请求给服务器(这个请求是还没带上 Cookie 的)
3. 服务器设置 Cookie 并发送给浏览器(当然也可以不设置)
4. 浏览器将 Cookie 保存下来
5. 接下来,以后的每一次请求,都会带上这些 Cookie,发送给服务器

Cookie 的属性选项

每个 Cookie 都有一定的属性,如什么时候失效,要发送到哪个域名,哪个路径等等。在设置任一个 Cookie 时都可以设置相关的这些属性,当然也可以不设置,这时会使用这些属性的默认值。

expires / max-age

expires / max-age 都是控制 Cookie 失效时刻的选项。如果没有设置这两个选项,则默认有效期为 session,即会话 Cookie。这种 Cookie 在浏览器关闭后就没有了。

expires

expires 选项用来设置 Cookie 什么时间内有效,expires 其实是 Cookie 失效日期。
expires 必须是 GMT 格式的时间(可以通过 new Date().toGMTString() 或者 new Date().toUTCString() 来获得)

const http = require("http");
let server = http.createServer(function(req,res){
    if(req.url === "/"){
        let cookie0 = "testName0=testValue0;expires=" + (new Date(Date.now() + 10000).toGMTString());
        let cookie1 = "testName1=testValue1";
        res.setHeader("Set-Cookie",[cookie0,cookie1]);
        res.end();
    }
});
server.listen(8080);

上面的代码服务器设置了两个 Cookie,一个设置了失效时刻,另外一个没有设置,也就是默认的失效时刻 session。现在我们重启服务并且刷新一下页面。

node axios设置cookie_默认值

现在响应头部已经加上了响应的设置失效时刻的字段了。在控制台输入下面的代码。

console.log(`现在的 cookie 是:${document.cookie}`)
setTimeout(() => {
  console.log(`5 秒后的 cookie 是:${document.cookie}`)
}, 5000)
setTimeout(() => {
  console.log(`10 秒后的 cookie 是:${document.cookie}`)
}, 10000)

node axios设置cookie_node.js_02

所以,Cookie 的失效时刻到了之后,通过 document.cookie 就访问不到这个 Cookie 了,当然以后发送请求也不会再带上这个失效的 Cookie 了。

max-age

expires 是 http/1.0 协议中的选项,在新的 http/1.1 协议中 expires 已经由 max-age 选项代替,两者的作用都是限制 Cookie 的有效时间。expires 的值是一个时间点 (Cookie 失效时刻 = expires),而 max-age 的值是一个以为单位时间段 (Cookie 失效时刻 = 创建时刻 + max-age)

const http = require("http");
let server = http.createServer(function(req,res){
    if(req.url === "/"){
        let cookie0 = "testName0=testValue0;max-age=1000";
        let cookie1 = "testName1=testValue1";
        res.setHeader("Set-Cookie",[cookie0,cookie1]);
        res.end();
    }
});
server.listen(8080);
优先级

如果同时设置了 max-age 和 expires,以 max-age 的时间为准。

const http = require("http");
let server = http.createServer(function(req,res){
    if(req.url === "/"){
        let cookie0 = "testName0=testValue0;
        let cookie1 = "testName1=testValue1;expires=" + (new Date(Date.now() + 30000).toGMTString()) + "; max-age=60000";
        let cookie2 = "testName2=testValue2; max-age=60000;
        res.setHeader("Set-Cookie",[cookie0,cookie1,cookie2]);
        res.end();
    }
});
server.listen(8080);

node axios设置cookie_node.js_03

domain 和 path

namedomainpath 可以标识一个唯一的 Cookie。domainpath 两个选项共同决定了 Cookie 何时被浏览器自动添加到请求头部中发送出去。

如果没有设置这两个选项,则会使用默认值。domain 的默认值为设置该 Cookie 的网页所在的域名,path 默认值为设置该 Cookie 的网页所在的目录。

httpOnly

这个选项用来设置 Cookie 是否能通过 js 去访问。默认情况下,Cookie 不会带 httpOnly 选项(即为空),客户端是可以通过 js 代码去访问(包括读取、修改、删除等)这个 Cookie 的。当 Cookie 带 httpOnly 选项时,客户端则无法通过 js 代码去访问(包括读取、修改、删除等)这个 Cookie。

看看代码吧,修改 main.js,保存重启服务,刷新页面。

const http = require("http");
let server = http.createServer(function(req,res){
    if(req.url === "/"){
        let cookie0 = "notHttpOnly=testValue";
        let cookie1 = "httpOnlyTest=testValue;httpOnly=true";
        res.setHeader("Set-Cookie",[cookie0,cookie1]);
        res.end();
    }
});
server.listen(8080);

node axios设置cookie_node axios设置cookie_04

看图,设置了 httpOnly 的 Cookie 多了一个勾。而且通过 document.cookie 无法访问到那个 Cookie。

node axios设置cookie_node axios设置cookie_05

在客户端是不能通过 js 代码去设置 一个 httpOnly 类型的 Cookie 的,这种类型的 Cookie 只能通过服务端来设置,发送请求的时候,我们看到请求头还是会带上这个设置了 httpOnly 的 Cookie.

设置 Cookie

明确一点:Cookie 可以由服务端设置,也可以由客户端设置。看到这里相信大家都可以理解了吧。

服务端设置 Cookie

看回刚刚的那张图,我们设置了很多个 Cookie。

node axios设置cookie_默认值_06

  • 一个 Set-Cookie 字段只能设置一个 Cookie,当你要想设置多个 Cookie,需要添加同样多的 Set-Cookie 字段
  • 服务端可以设置 Cookie 的所有选项:expires、domain、path、secure、HttpOnly

客户端设置 Cookie

在网页即客户端中我们也可以通过 js 代码来设置 Cookie。

设置
document.cookie = 'name=value'

可以设置 Cookie 的下列选项:expires、domain、path,各个键值对之间都要用 ;空格 隔开

document.cookie='name=value; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/';
secure

只有在 https 协议的网页中,客户端设置 secure 类型的 Cookie 才能成功

HttpOnly

客户端中无法设置 HttpOnly 选项

删除 Cookie

Cookie 的 name、path 和 domain 是唯一标识一个 Cookie 的。我们只要将一个 Cookie 的 max-age 设置为 0,就可以删除一个 Cookie 了。

let removeCookie = (name, path, domain) => {
  document.cookie = `${name}=; path=${path}; domain=${domain}; max-age=0`
}

Cookie 的作用域和作用路径

作用域

在说这个作用域之前,我们先来对域名做一个简单的了解。

子域,是相对父域来说的,指域名中的每一个段。各子域之间用小数点分隔开。放在域名最后的子域称为最高级子域,或称为一级域,在它前面的子域称为二级域。

news.163.comsports.163.com 是子域,163.com 是父域。

当 Cookie 的 domain 为 news.163.com,那么访问 news.163.com 的时候就会带上 Cookie;
当 Cookie 的 domain 为 163.com,那么访问 news.163.comsports.163.com就会带上 Cookie

作用路径

当 Cookie 的 domain 是相同的情况下,也有是否带上 Cookie 也有一定的规则。

在子路径内可以访问访问到父路径的 Cookie,反过来就不行。

看看例子,还是先修改 main.js

const http = require("http");
let server = http.createServer(function(req,res){
    if(req.url === "/parent"){
        let cookie = "parent-name=parent-value;path=/parent";
        res.setHeader("Set-Cookie",cookie);
        res.end();
    }else if(req.url === "/parent/childA"){
        let cookie = "child-name-A=child-value-A;path=/parent/childA";
        res.setHeader("Set-Cookie",cookie);
        res.end();
    }else if(req.url === "/parent/childB"){
        let cookie = "child-name-B=child-value-B;path=/parent/childB";
        res.setHeader("Set-Cookie",cookie);
        res.end();
   }else{
        res.end("Error!");
   }
});
server.listen(3000);
下面这里的 “域” 应该改为路径

node axios设置cookie_客户端_07


node axios设置cookie_node axios设置cookie_08

node axios设置cookie_客户端_09