从输入url到页面显示都经历了什么

从输入url到页面显示都经历了什么

(可参考简书知乎

精简总结

  1. 客户端(浏览器)
    • DNS解析:通过输入的域名解析到一个IP地址;
    • 建立TCP连接(三次握手);
    • 发送http请求
  2. 服务端
    server接收到http请求(Request),处理,并返回HTTP报文(Response)。(具体处理过程在“开发博客项目之接口(1)”中的“nodejs处理HTTP请求”中)(res返回的都是字符串,只是形式不同,通过content-type来决定,比如html或者json)
  3. 客户端(浏览器)
    接收到服务端返回的数据,处理数据(如渲染页面,执行js)

具体流程

客户端 建立连接 发送请求

  • DNS解析:
    首先需要找到这个url域名的服务器ip,为了寻找这个ip,先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
    如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
    如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
    如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询
  • 建立TCP连接(三次握手):
    客户端发送一个TCP连接请求报文-》服务端回送一个TCP确认响应+请求连接报文-》客户端向服务器发送一个 “TCP确认”的报文
  • 发送http请求
    通过三次握手建立了可靠的tcp连接后就可以进行是数据传输了。浏览器根据这个ip以及相应的端口号,构造一个http请求,这个请求报文会包括这次请求的信息,主要是请求方法,请求说明和请求附带的数据,并将这个http请求封装在一个tcp包中,这个tcp包会依次经过传输层,网络层,数据链路层,物理层到达服务器。(ISO 模型中的第五个层次应用层就是http请求这一层,就不会经过了)

服务端 处理请求 发出响应

服务器收到 TCP 数据包后,会将 TCP 数据包中的 HTTP 请求报文解析出来,并发送 HTTP 响应给客户端,即返回相应的html给浏览器。

客户端 解析数据 渲染页面 断开连接

  • 构建DOM树:浏览器根据这个html来构建DOM树,在dom树的构建过程中如果遇到JS脚本和外部JS连接,则会停止构建DOM树和css解析(因为JS有可能修改DOM结构,或者通过改变html元素的字体大小改变css的rem)来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面
  • 构建CSS对象模型CSSOM:解析html过程中遇到引入了css,则会在解析html的同时解析css,根据外部样式,内部样式,内联样式构建CSS对象模型CSSOM
    • 建议CSS写在head中:页面边解析边渲染,如果把CSS写在HTML后,则先解析DOM树渲染在页面上,再生成CSSOM合成渲染树重新渲染在页面上,这样会有一个过程,用户可能会看到一个过程变化。所以在DOM树生成之前就先生成CSSOM会更好,这样当DOM树生成时就可直接和所有CSSOM进行合并,一步渲染完成
  • 合并为渲染树: CSSOM树构建完成后CSSOM树和DOM树合并为渲染树,这里主要做的是排除非视觉节点,比如script,meta标签和排除display为none的节点。
  • 最后浏览器将渲染树绘制到屏幕上显示。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)
    • 回流:浏览器去计算各个元素(盒模型)的位置和大小等
    • 重绘:当盒模型的位置,大小以及其他属性,如颜色,字体等确定下来之后,浏览器便开始绘制内容
  • 注意:在dom树的构建过程/渲染树的渲染过程中如果遇到JS脚本和外部JS连接,则会停止渲染(因为JS有可能修改DOM结构,或者通过改变html元素的字体大小改变css的rem)来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面
    • 总结代码放置顺序:CSS HTML JS
  • js的解析涉及同步、异步(宏任务与微任务)事件循环
  • 另外的HTTP请求: html文件中会含有 图片、视频、音频、js、jquery、css等其他资源,这些又是另外的HTTP请求。在解析DOM的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是4-6个,可能会通过一个网页产生很多的HTTP请求,请求越少性能越好
  • 为提高性能要关注缓存(强缓存和协商缓存),缓存一般通过Cache-Control、Last-Modify、Expires等首部字段控制。
    • Cache-Control和Expires的区别在于Cache-Control使用相对时间,Expires使用的是基于服务器 端的绝对时间,因为存在时差问题,一般采用Cache-Control。
    • 在请求这些有设置了缓存的数据时,如是强缓存,则不发送请求,直接从缓存中获取数据
    • 如是协商缓存,则会发送请求到服务器,如果上一次 响应设置了ETag值,则会在这次请求的时候作为If-None-Match的值交给服务器校验,如果一致,继续校验客户端发送的IF-Modified-Since与服务端的 Last-Modified是否一致,没有设置ETag则直接验证Last-Modified,都一致则返回304(Not Changed)告知浏览器可以直接从缓存获取,否则返回最新的资源内容
  • 连接结束:
    • 浏览器请求的资源已经被服务器完全发送给浏览器时,浏览器会进行 TCP 四次挥手,释放 TCP 连接
      1. 客户端向服务器发送 FIN 报文,表示客户端不再发送数据。
      2. 服务器收到 FIN 报文,向客户端发送 ACK 报文,表示服务器已经接收到客户端的 FIN 报文。
      3. 服务器向客户端发送 FIN 报文,表示服务器不再发送数据。
      4. 客户端收到 FIN 报文,向服务器发送 ACK 报文,表示客户端已经接收到服务器的 FIN 报文。

实例演示

客户端(浏览器)进行DNS解析

  • DNS解析的过程就是寻找哪台机器上有你需要资源的过程。
  • 当你在浏览器中输入一个地址时,例如http://www.baidu.com,其实不是百度网站真正意义上的地址。
  • 互联网上每一台计算机的唯一标识是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度的网址。所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到IP地址的转换。
  • 当然如果你直接输入的是另一台电脑的IP地址来访问它,那么则不存在这一步。
  • 例子:
    • 浏览器或者操作系统本身是有缓存的,如果是 缓存过期 或者 没有缓存 又或者是 第一次访问,浏览器 或者 操作系统 就会去域名工程商通过域名去DNS服务器换取IP地址。(更多详情需要复习 计算机网络 )
    • server端就是这个IP地址的服务器!!
      DNS解析
      (百度比较大,全国各地使用人数多,看到的IP地址不一样是正常的,就算是自己今天看到的和昨天看到的不一样也是很正常的)

建立TCP连接

  • 客户端找到IP地址之后就会和这个IP地址的服务器(server端)进行TCP连接(三次握手)
握手 作用
第1次 客户端(浏览器)询问服务器(server端):“你是否可以使用?”【客户机发送一个TCP连接请求报文
第2次 服务器(server端)回答客户端(浏览器):“我可以用。”【服务器回送一个TCP确认响应报文
第3次 客户端(浏览器)告诉服务器(server端):“我知道啦,我来访问你啦。”【客户机向服务器发送一个 “TCP确认”的报文

tcp三次握手

客户端(浏览器)发送http请求

  • 例子:
    • 客户端(浏览器)通过url使用get方法向服务端发送http请求,头部包含了请求信息,他们告诉了服务端这个客户端(浏览器)是什么样子的以及有什么要求。
      发送http请求
      (注意:请求req都是客户端发起的,而回复res都是服务端做的。)

HTTP请求报文

  • HTTP协议使用TCP协议进行传输,在应用层协议发起交互之前,首先是TCP的三次握手。完成了TCP三次握手后,浏览器向服务器发出一个 HTTP 请求

  • HTTP请求报文 是由三部分组成: 请求行, 首部行和报文主体

  • HTTP请求报文(get):HTTP请求报文(get)

  • HTTP请求报文(post):HTTP请求报文(post)

  • 请求行(请求方法 URI 协议/版本)

    • 例如:GET/sample.jsp HTTP/1.1“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本
    • POST/sample.jsp HTTP/1.1,POST方法之后是URI(“/sample.jsp”),表示请求的页面地址,“/”表示服务器的根目录。之后是表示http的版本。
  • 首部行包含许多有关的客户端环境和请求正文的有用信息。例如,声明浏览器所用的语言,请求正文的长度等。例如:

    • Accept:image/gif.image/jpeg.*/*请求的对象类型。如果是“/”表示任意类型,如果是指定的类型,则会变成“type/”。
    • Accept-Language:zh-cn使用的语言种类
    • Connection:Keep-Alive对于HTTP连接的处理,keep-alive表示保持连接,如果是在响应报文中发送页面完毕就会关闭连接,状态变为close。
    • Host:localhost连接的目标主机,如果连接的服务器是非标准端口,在这里会出现使用的非标准端口。
    • User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)提供了客户端浏览器的类型和版本
    • Accept-Encoding:gzip,deflate.页面编码种类
  • 报文主体

    • 报文首部 和 报文主体 之间是一个空行,这个行非常重要,它表示 报文首部 已经结束,接下来的是 报文主体。
    • 报文主体 中可以包含客户提交的查询字符串信息
      username=jinqiao&password=1234
    • 在实际应用中,HTTP请求报文主体可以包含更多的内容。

server端接收http请求,处理并返回

  • server端就是这个IP地址的服务器
  • server端接到HTTP请求后,会根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件,再将得到的 HTML 文件发送给浏览器(客户端),最后返回HTTP响应报文
  • 例子:
    • 服务器 通过Response Headers 告诉客户端:我反回的是html代码而不是纯文本server端回复的信息

HTTP响应报文

  • 当收到get或post等方法发来的请求后,服务器就要对报文进行响应。
  • HTTP响应报文也是由三部分组成: 状态行, 首部行和报文实体HTTP响应报文
  1. 状态行(服务器的http版本,状态码,状态短语)

    • 1xx:指示信息–表示请求已接收,继续处理(继续进程,在发送post后可以收到该应答)。
    • 2xx:成功–表示请求已被成功接收、理解、接受。(在发送get后返回)
      • 200 OK:请求成功,请求的对象在这个报文后面
    • 3xx:重定向–要完成请求必须进行更进一步的操作。
      • 301 Moved Permanently:请求的对象已转移,新的URL在响应报文的Location:首部行中指定。
    • 4xx:客户端错误–请求有语法错误或请求无法实现。
      • 400 Bad Request:请求报文不为服务器理解
      • 404 Not Found:请求的文档没有在该服务器上发现
    • 5xx:服务器端错误–服务器未能实现合法的请求。
      • 505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP版本
  2. 首部行

    • Server:服务器软件版本
    • Content-Type:应答请求后返回的数据类型
    • Date:发送日期(当前服务器的时间)
    • Content-Length(对象长度)
    • Connection:close为关闭连接,抓包可以发现在响应返回后服务器向客户端发出fin包单向关闭了连接。
    • Expires:在某个时间以前可以不用重新缓存该页面。(cookie的有效期)
    • cache-control表示对页面是否进行缓存。
    • Pragma的参数no-cache表示对页面不进行缓存。
  3. 报文实体

    • 服务器返回给浏览器的文本信息,通常HTML, CSS, JS, 图片等文件就放在这一部分。

对比 请求报文、响应报文

实体首部字段

客户端(浏览器)解析数据 渲染页面

  • 客户端(浏览器)接收到server端返回的 HTML 文件 后就会解析这些html代码,在还没有完全接收 HTML 文件时便开始渲染、显示网页
  • 在执行 HTML 中代码时,先是解析html,解析html过程中遇到引入了css,则会在解析html的同时解析css。
  • 如果遇到引入了js,则会解析js,停止html和css解析(因为JS有可能修改DOM结构,或者通过改变html元素的字体大小改变css的rem)。等解析完js再解析剩下未解析完的html和css。
  • 页面显示之后的 加载图片、加载js、加载jquery、加载css等,这些又是另外的HTTP请求。可能会通过一个网页产生很多的HTTP请求,请求越少性能越好。

边解析边渲染

  1. 首先浏览器解析HTML文件构建DOM树
  2. 然后解析CSS文件构建 CSS对象模型:解析提取的CSS文件,并根据选择器类型分到不同的“存储桶”,例如元素,类,ID等。根据找到的选择器,它确定应将哪些 CSS规则 应用于DOM中的哪些节点,并根据需要向其附加样式
    CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明。)
  3. 等到渲染树构建完成后,浏览器开始根据DOM树合成渲染树(将 渲染树 放在合适的HTML元素中)
    渲染树图解
  4. 最后浏览器将渲染树绘制到屏幕上显示。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)
  5. 渲染过程中遇到<script>则暂停渲染(因为JS有可能修改DOM结构,或者通过改变html元素的字体大小改变css的rem),优先加载并执行JS代码,完成再继续渲染
    图解全过程

浏览器 reflow(回流)和repain(重绘)

  • 参考简书参考掘金
  • 总结
    • 会引起元素位置/内容变化、布局、隐藏的就会**reflow(回流)**,如:窗口大小改变、字体大小改变、以及元素位置改变,都会引起周围的元素改变他们以前的位置。
    • 不会引起位置、布局变化,只是影响元素的外观的,比如改变背景颜色等,只会**repaint(重绘)**。
    • 回流必将引起重绘,而重绘不一定会引起回流。因为在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,这就是回流必将引起重绘。
  • DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow(回流);
    • 会导致回流的操作:
      • 页面首次渲染
      • 浏览器窗口大小发生改变
      • 元素尺寸或位置发生改变
      • 元素内容变化(文字数量图片大小等等)
      • 元素字体大小变化
      • 添加或者删除可见的DOM元素
      • 激活CSS伪类(例如::hover
      • 查询某些属性或调用某些方法(常用且会导致回流的属性和方法)
        • clientWidth、clientHeight、clientTop、clientLeft
          offsetWidth、offsetHeight、offsetTop、offsetLeft
          scrollWidth、scrollHeight、scrollTop、scrollLeft
          scrollIntoView()、scrollIntoViewIfNeeded()
          getComputedStyle()
          getBoundingClientRect()
          scrollTo()
  • 当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility:hidden等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为**repain(重绘)**。
  • 页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain
减少回流、重绘的方法
  • 合并DOM操作 :比如我们要向页面添加多个img元素,如果单独加进去就会频繁的回流+重绘,此时我们就可以使用document.createDocumentFragment()将多个img合并到Fragment中再统一加入。
  • 避免频繁读取会引发回流/重绘的属性(见上),如果确实需要多次使用,就用一个变量缓存起来。
  • 将动画效果应用到position属性为absolute或fixed的元素上,对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

JS的解析(同步、异步)

  • JS的解析是由浏览器中的JS解析引擎完成的
  • JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。(HTML5提供的Web Workers API可以让浏览器作为宿主环境提供给JS一个多线程运行的环境
  • 但是又存在某些任务比较耗时,如 IO读写 等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)
  • 同步任务就是放在主线程(执行栈)上执行的任务,异步任务是放在任务队列中的任务。【注意:异步任务中有两个任务队列:宏任务和微任务
  • JS的执行机制就可以看做是一个 主线程(执行栈) 加上一个 任务队列(task queue)。
JS的执行步骤(事件循环)
  • 事件循环是解决javaScript单线程运行阻塞的一种机制
  • 所有的同步任务在主线程上执行,形成一个执行栈异步任务有了运行结果就会在任务队列中放置一个事件。脚本运行时先依次运行执行栈中的所有同步任务,执行完毕后取出 微任务 队列中的所有任务顺序执行;然后开始检查是否需要DOM渲染,需要则渲染,之后再取 宏任务,每次宏任务结束时都给一个DOM渲染的机会,周而复始,直至两个队列的任务都取完。
  • 在此过程中,主线程要做的就是从任务队列中去执行事件,执行完毕,再取事件,再执行事件…这样不断取事件,执行事件的循环机制就叫做事件循环机制
  • 注意:异步任务被挂起时宏任务会由浏览器的引擎(web api,即不属于ES语法的代码)去执行他们,而微任务和同步任务则是由JS的引擎去执行。又js处理比浏览器快,所以 同步->微任务->宏任务->微任务…
  • 总结事件循环:
    执行栈(第一个宏任务) 全部执行完毕后 –>清空 微任务 –>尝试DOM渲染–>取出一个 宏任务 –> 执行完毕后–>清空 微任务 -> 尝试DOM渲染–>无线循环
宏任务和微任务
  • 宏任务先于微任务执行
  • MacroTask(宏任务)
    • **script(整体代码):**第一个宏任务队列中只有一个任务: 执行主线程的js代码
    • 定时器: setTimeout、setInterval
    • ajax
    • DOM 事件
    • I/O
    • UI交互事件
  • MicroTask(微任务)
    • Promise.then()【但是Promise 的函数体会立刻执行】
    • async 函数中 await当行代码 后面的内容【async和await当行代码立即执行】
    • Process.nextTick(Node独有)
    • MutationObserver(具体使用方式查看这里)
  • 挂起异步任务时,JS 引擎会将所有异步任务按照类别分到这两个队列中,首先在 宏任务 的队列中取出第一个任务,执行栈执行完毕后,取出 微任务 队列中的所有任务顺序执行,接着检查是否需要DOM渲染,需要则渲染,之后再取 宏任务,查看是否有微任务再队列中,周而复始,直至两个队列的任务都取完。
  • 注意:同步任务也属于宏任务,所以第一个取出的宏任务是同步任务
    宏任务和微任务
事件循环例子(面试题)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
console.log('script start')

setTimeout(function() {
console.log('timer over')
}, 0)

Promise.resolve().then(function() {
console.log('promise1')
}).then(function() {
console.log('promise2')
})

console.log('script end')

// script start
// script end
// promise1
// promise2
// timer over
  1. 整体代码script是宏任务,所以先打印script start
  2. 再执行到setTimeout属于异步任务,也是宏任务的一种,放到 宏任务队列 里面
  3. 接着就执行到Promise也是异步任务,但是属于微任务,进入到 微任务队列
  4. 然后执行到 script的最后打印出script end,主线程(执行栈)被清空
  5. 这里要注意的是主线程一旦全部执行完毕就会取清空微任务,所以接下来微任务队列中的 Promise.then()被加入到主线程中执行。执行了回调,打印出promise1,同时产生了新的微任务 Promise.then(),执行完毕后,主线程又被清空
  6. 微任务队列里还有刚刚产生的Promise.then(),又被加入到主线程执行打印出promise2
  7. 此时微任务队列和主线程都被清空,接着在宏任务队列里取出一个宏任务加入到主线程中执行 setTimeout callback,打印出setTimeout
  8. 这时主线程、微任务队列、宏任务队列都被清空,代码执行完毕,所以最后的执行结果为script start、script end、promise1、promise2、setTimeout。如果宏任务队列和微任务队列还没清空,就会:执行栈 全部执行完毕后 –>清空 微任务 –>会取出一个 宏任务 –> 执行完毕后–>清空 微任务 -> 无线循环,这就是我们所说的事件循环(Event Loop),也就是javascript的执行机制

连接结束

  • 浏览器请求的资源已经被服务器完全发送给浏览器时,浏览器会进行 TCP 四次挥手,释放 TCP 连接
    1. 客户端向服务器发送 FIN 报文,表示客户端不再发送数据。
    2. 服务器收到 FIN 报文,向客户端发送 ACK 报文,表示服务器已经接收到客户端的 FIN 报文。
    3. 服务器向客户端发送 FIN 报文,表示服务器不再发送数据。
    4. 客户端收到 FIN 报文,向服务器发送 ACK 报文,表示客户端已经接收到服务器的 FIN 报文。

补充

  • 浏览器在解析过程中,如果遇到请求外部资源时,如图像,iconfont,JS等。这些又是另外的HTTP请求,浏览器将重复以上所有过程下载该资源。可能会通过一个网页产生很多的HTTP请求,请求越少性能越好。
  • 请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程
  • 原因是因为JS有可能修改DOM结构,或者通过改变html元素的字体大小改变css的rem,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因
  • CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕

  • 堆表示一大块非结构化的内存区域。对象,数据被存放在堆中。

  • 栈在javascript中又称执行栈、调用栈,是一种后进先出的数组结构,
  • Javascript 有一个 主线程(main thread)和 调用栈(或执行栈call-stack),主线各所有的任务都会被放到执行栈等待主线程执行
  • JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完该函数后,函数就会从栈顶移出,直到栈内被清空

举个例子

1
2
3
4
5
6
7
8
9
10
11
function foo(b) {
var a = 10;
return a + b + 11;
}

function bar(x) {
var y = 3;
return foo(x * y);
}

console.log(bar(7)); // 返回 42
  • 调用 bar 时,创建了第一个帧 ,帧中包含了 bar 的参数和局部变量。当 bar 调用 foo 时,第二个帧就被创建,并被压到第一个帧之上,帧中包含了 foo 的参数和局部变量。当 foo 返回时,最上层的帧就被弹出栈(剩下 bar 函数的调用帧 )。当 bar 返回的时候,栈就空了
  • 注意:这里的堆栈,是数据结构的堆栈,不是内存中的堆栈(内存中的堆栈,堆存放引用类型的数据,栈存放基本类型的数据)

队列

队列即任务队列Task Queue,是一种先进先出的一种数据结构。在队尾添加新元素,从队头移除元素。
队列图示


cookie

  • cookie是一种类似缓存的机制,它保存在一个本地的文本文件中,其主要作用是在发送请求时将cookie放在请求首部中发送给服务器,服务器收到cookie后查找自己已有的cookie信息,确定客户端的身份,然后返回相应的页面。
  • cookie的方便之处在于可以保持一种已登录的状态,例如:我们注册一个论坛,每次访问都需要进行填写用户名和密码然后登录。而使用了cookie后,如果cookie没有到达过期时间,那么我们只需在第一次登录时填写信息然后登录,以后的访问就可以省略这一步骤。

在HTTP协议中,cookie的交互过程

  1. 首先是三次握手建立TCP连接
  2. 然后客户端发出一个http request,(第一次请求时)这个request中不包含任何cookie信息:request中不包含任何cookie信息
  3. 服务器收到这个报文后,针对request method作出响应动作,在响应报文的头部(首部行)加入了set-cookie段,set-cookie段中给出了cookie的id,过期时间以及参数path,path是表示在哪个虚拟目录路径下的页面可以读取使用该cookie。响应报文
  4. 客户端接受到这些信息后,在以后的http request中就会将自己的cookie段用这些信息填充
  5. 如果用户在连接中通过了服务器相应的认证程序,服务器会添加一个cdb_authset-cookie中,这个段表示了客户端的认证信息,而客户端以后在访问过程中也会将cdb_auth信息写入自己的cookie字段。服务器每次收到http request后读取cookie,然后根据cookie的信息返回不同的页面。例如,没有通过认证的客户端在request中不会有cdb_auth,因此服务器读取cookie后,不会将通过认证的客户端的页面返回给该客户端。请求报文

, , ,