从输入url到页面显示都经历了什么
精简总结
- 客户端(浏览器):
- DNS解析:通过输入的域名解析到一个IP地址;
- 建立TCP连接(三次握手);
- 发送http请求。
- 服务端:
server接收到http请求(Request),处理,并返回HTTP报文(Response)。(具体处理过程在“开发博客项目之接口(1)”中的“nodejs处理HTTP请求”中)(res返回的都是字符串,只是形式不同,通过content-type来决定,比如html或者json) - 客户端(浏览器):
接收到服务端返回的数据,处理数据(如渲染页面,执行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 连接
- 客户端向服务器发送 FIN 报文,表示客户端不再发送数据。
- 服务器收到 FIN 报文,向客户端发送 ACK 报文,表示服务器已经接收到客户端的 FIN 报文。
- 服务器向客户端发送 FIN 报文,表示服务器不再发送数据。
- 客户端收到 FIN 报文,向服务器发送 ACK 报文,表示客户端已经接收到服务器的 FIN 报文。
- 浏览器请求的资源已经被服务器完全发送给浏览器时,浏览器会进行 TCP 四次挥手,释放 TCP 连接
实例演示
客户端(浏览器)进行DNS解析
- DNS解析的过程就是寻找哪台机器上有你需要资源的过程。
- 当你在浏览器中输入一个地址时,例如
http://www.baidu.com
,其实不是百度网站真正意义上的地址。 - 互联网上每一台计算机的唯一标识是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度的网址。所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到IP地址的转换。
- 当然如果你直接输入的是另一台电脑的IP地址来访问它,那么则不存在这一步。
- 例子:
- 浏览器或者操作系统本身是有缓存的,如果是 缓存过期 或者 没有缓存 又或者是 第一次访问,浏览器 或者 操作系统 就会去域名工程商去通过域名去DNS服务器换取IP地址。(更多详情需要复习 计算机网络 )
- server端就是这个IP地址的服务器!!
(百度比较大,全国各地使用人数多,看到的IP地址不一样是正常的,就算是自己今天看到的和昨天看到的不一样也是很正常的)
建立TCP连接
- 客户端找到IP地址之后就会和这个IP地址的服务器(server端)进行TCP连接(三次握手)
握手 | 作用 |
---|---|
第1次 | 客户端(浏览器)询问服务器(server端):“你是否可以使用?”【客户机发送一个TCP连接请求报文 】 |
第2次 | 服务器(server端)回答客户端(浏览器):“我可以用。”【服务器回送一个TCP确认响应报文】 |
第3次 | 客户端(浏览器)告诉服务器(server端):“我知道啦,我来访问你啦。”【客户机向服务器发送一个 “TCP确认”的报文】 |
- tcp三次握手和四次挥手具体可参考前端基础-HTTP/HTML/浏览器(2)
客户端(浏览器)发送http请求
- 例子:
- 客户端(浏览器)通过url使用get方法向服务端发送http请求,头部包含了请求信息,他们告诉了服务端这个客户端(浏览器)是什么样子的以及有什么要求。
(注意:请求req都是客户端发起的,而回复res都是服务端做的。)
- 客户端(浏览器)通过url使用get方法向服务端发送http请求,头部包含了请求信息,他们告诉了服务端这个客户端(浏览器)是什么样子的以及有什么要求。
HTTP请求报文
HTTP协议使用TCP协议进行传输,在应用层协议发起交互之前,首先是TCP的三次握手。完成了TCP三次握手后,浏览器向服务器发出一个 HTTP 请求。
HTTP请求报文 是由三部分组成: 请求行, 首部行和报文主体。
HTTP请求报文(get):
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代码而不是纯文本:
HTTP响应报文
- 当收到get或post等方法发来的请求后,服务器就要对报文进行响应。
- HTTP响应报文也是由三部分组成: 状态行, 首部行和报文实体。
状态行(服务器的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版本
首部行:
- Server:服务器软件版本
- Content-Type:应答请求后返回的数据类型
- Date:发送日期(当前服务器的时间)
- Content-Length(对象长度)
- Connection:close为关闭连接,抓包可以发现在响应返回后服务器向客户端发出fin包单向关闭了连接。
- Expires:在某个时间以前可以不用重新缓存该页面。(cookie的有效期)
- cache-control表示对页面是否进行缓存。
- Pragma的参数no-cache表示对页面不进行缓存。
报文实体:
- 服务器返回给浏览器的文本信息,通常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请求,请求越少性能越好。
边解析边渲染
- 首先浏览器解析HTML文件构建DOM树
- 然后解析CSS文件构建 CSS对象模型:解析提取的CSS文件,并根据选择器类型分到不同的“存储桶”,例如元素,类,ID等。根据找到的选择器,它确定应将哪些 CSS规则 应用于DOM中的哪些节点,并根据需要向其附加样式。
(CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明。) - 等到渲染树构建完成后,浏览器开始根据DOM树合成渲染树(将 渲染树 放在合适的HTML元素中)
- 最后浏览器将渲染树绘制到屏幕上显示。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)
- 渲染过程中遇到
<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()
- clientWidth、clientHeight、clientTop、clientLeft
- 会导致回流的操作:
- 当页面中元素样式的改变并不影响它在文档流中的位置时(例如: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渲染的机会,周而复始,直至两个队列的任务都取完。
- 任务队列 分为(但不包含) 宏任务队列 和 微任务队列(因为script中的同步任务也属于宏任务)。
- 宏任务先于微任务执行(第一个执行的宏任务是script中的同步任务)
- 每一次执行栈结束都会给一次DOM渲染的机会
- DOM 渲染前触发微任务,DOM 渲染后触发宏任务(可参考“JS异步进阶”中”event-loop图解宏任务和微任务与DOM渲染的执行顺序”)
- 补充:任务队列中除了完成的异步任务还会有被触发的DOM事件,图示可参考“JS异步进阶”中的“DOM事件和event loop的关系”
- 在此过程中,主线程要做的就是从任务队列中去执行事件,执行完毕,再取事件,再执行事件…这样不断取事件,执行事件的循环机制就叫做事件循环机制。
- 注意:异步任务被挂起时宏任务会由浏览器的引擎(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 | console.log('script start') |
- 整体代码script是宏任务,所以先打印
script start
- 再执行到setTimeout属于异步任务,也是宏任务的一种,放到 宏任务队列 里面
- 接着就执行到Promise也是异步任务,但是属于微任务,进入到 微任务队列
- 然后执行到 script的最后打印出
script end
,主线程(执行栈)被清空 - 这里要注意的是主线程一旦全部执行完毕就会取清空微任务,所以接下来微任务队列中的
Promise.then()
被加入到主线程中执行。执行了回调,打印出promise1
,同时产生了新的微任务Promise.then()
,执行完毕后,主线程又被清空了 - 微任务队列里还有刚刚产生的
Promise.then()
,又被加入到主线程执行打印出promise2
- 此时微任务队列和主线程都被清空,接着在宏任务队列里取出一个宏任务加入到主线程中执行
setTimeout callback
,打印出setTimeout
- 这时主线程、微任务队列、宏任务队列都被清空,代码执行完毕,所以最后的执行结果为script start、script end、promise1、promise2、setTimeout。如果宏任务队列和微任务队列还没清空,就会:执行栈 全部执行完毕后 –>清空 微任务 –>会取出一个 宏任务 –> 执行完毕后–>清空 微任务 -> 无线循环,这就是我们所说的事件循环(Event Loop),也就是javascript的执行机制。
连接结束
- 浏览器请求的资源已经被服务器完全发送给浏览器时,浏览器会进行 TCP 四次挥手,释放 TCP 连接
- 客户端向服务器发送 FIN 报文,表示客户端不再发送数据。
- 服务器收到 FIN 报文,向客户端发送 ACK 报文,表示服务器已经接收到客户端的 FIN 报文。
- 服务器向客户端发送 FIN 报文,表示服务器不再发送数据。
- 客户端收到 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 | function foo(b) { |
- 当调用 bar 时,创建了第一个帧 ,帧中包含了 bar 的参数和局部变量。当 bar 调用 foo 时,第二个帧就被创建,并被压到第一个帧之上,帧中包含了 foo 的参数和局部变量。当 foo 返回时,最上层的帧就被弹出栈(剩下 bar 函数的调用帧 )。当 bar 返回的时候,栈就空了。
- 注意:这里的堆栈,是数据结构的堆栈,不是内存中的堆栈(内存中的堆栈,堆存放引用类型的数据,栈存放基本类型的数据)
队列
队列即任务队列Task Queue,是一种先进先出的一种数据结构。在队尾添加新元素,从队头移除元素。
cookie
- cookie是一种类似缓存的机制,它保存在一个本地的文本文件中,其主要作用是在发送请求时将cookie放在请求首部中发送给服务器,服务器收到cookie后查找自己已有的cookie信息,确定客户端的身份,然后返回相应的页面。
- cookie的方便之处在于可以保持一种已登录的状态,例如:我们注册一个论坛,每次访问都需要进行填写用户名和密码然后登录。而使用了cookie后,如果cookie没有到达过期时间,那么我们只需在第一次登录时填写信息然后登录,以后的访问就可以省略这一步骤。
在HTTP协议中,cookie的交互过程:
- 首先是三次握手建立TCP连接
- 然后客户端发出一个http request,(第一次请求时)这个request中不包含任何cookie信息:
- 当服务器收到这个报文后,针对request method作出响应动作,在响应报文的头部(首部行)加入了set-cookie段,set-cookie段中给出了cookie的id,过期时间以及参数path,path是表示在哪个虚拟目录路径下的页面可以读取使用该cookie。
- 客户端接受到这些信息后,在以后的http request中就会将自己的cookie段用这些信息填充。
- 如果用户在连接中通过了服务器相应的认证程序,服务器会添加一个
cdb_auth
到set-cookie
中,这个段表示了客户端的认证信息,而客户端以后在访问过程中也会将cdb_auth
信息写入自己的cookie
字段。服务器每次收到http request后读取cookie,然后根据cookie的信息返回不同的页面。例如,没有通过认证的客户端在request中不会有cdb_auth
,因此服务器读取cookie后,不会将通过认证的客户端的页面返回给该客户端。