以下是我学习web开发以来对于http相关知识的理解,如理解有误之处,望大佬们多多指点。
一、cookie和session
Cookie(机制)
1、服务器通过在http的响应头带上set-Cookie,可以设置该域名对应的Cookie值
2、浏览器访问指定域名时,必须在request 头部带上Cookie值
3、Cookie可以设置过期时间,到达过期时间,浏览器会自动清除该Cookie
Session(应用)
1、Session是对Cookie这种机制的一种应用,所以说Cookie是Session的基石
2、Session一般用来识别用户的,因为http协议本身是无连接状态的,需要通过Cookie中携带的SeesionID来判断请求的是哪个用户
3、SeesionID一般都是一串随机数字,一般通过在服务器的内存中存储 随机数(SeesionID) 对应 用户(用户常用的个人信息) 的哈希表,可以快速使用SeesionID找到对应的用户信息
二、浏览器的缓存机制
1、缓存分为两种缓存,强缓存(命中缓存条件则直接使用缓存资源)和协商缓存(当发现有缓存资源时,会发http报文进行确认,确认资源没被修改则使用缓存资源)
2、强缓存,有两种配置方式,通过服务器响应静态资源的response头部加入[Expires] 或者 [Cache-Control] 字段,进行配置
① [Expires](早期方案)使用的方式是:服务器在responese头部中发送Expires: Mon,10 Dec 2018 02:25:22GMT,意思是告诉浏览器 该静态资源过期的具体时间(绝对时间,以浏览器本地时间为准)
② [Cache-Control] 使用的方式是:服务器在responese头部中发送 Cache-Control: max-age=300 ,意思是告诉浏览器该静态资源有效的相对时间,指的是从接收到资源以后开始计时的300秒(相对时间)
③ 强缓存的缺点: [Expires]和[Cache-Control] 共有缺点,缓存的静态资源在过期时间内,服务器进行了更改,客户端还是依旧使用缓存资源,因为该资源没有过期。
解决的办法:通过更新HTML中引用资源的URL,比如在最后加上查询参数 ?v=1 ,让浏览器主动放弃缓存,加载新缓存。
④ 强缓存的优点:
只要命中强缓存,浏览器就会直接使用缓存文件,不会向服务器发送请求,速度会更快。
3、协商缓存,有两种常见使用方式,通过服务器响应静态资源的response头部加入[ETag](下次协商的request带上[If-None-Match]) 或者[Last-Modified](下次协商的request带上[If-Modified-Since]) 。
① [ETag] 使用的方式是: 服务器在responese头部中发送 ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q",ETag中携带的值其实就是该文件的摘要(类似MD5,代表该文件独一无二的值),浏览器通过存储该值,在下次需要请求静态资源时的request包头中加入 If-None-Match:W/"e-cbxLFQW5zapn79tQwb/g6Q" ,告诉服务器当前缓存文件的摘要,服务器会取出该文件,计算文件摘要,若值与浏览器返回的值一致,则给浏览器返回304表示可以使用缓存中的资源。
② [Last-Modified] 使用的方式是: 服务器在responese头部中发送Last-Modified:Sun, 24 Jun 2018 15:37:08 GMT,Last-Modified中携带的值其实就是该文件的在服务器是最后的修改时间,浏览器通过存储该值,在下次需要请求静态资源时的request包头中加入 If-Modified-Since:Sun, 24 Jun 2018 15:37:08 GMT ,告诉服务器当前缓存文件的最后修改时间(指上次在服务器中的),服务器会取出该文件,查询文件最后修改时间,若值与浏览器返回的值一致,则给浏览器返回304表示可以使用缓存中的资源。
③ 两者的缺点,以及解决办法
[ETag] 的缺点:当服务器采用集群负载均衡的方式搭建时,每一台服务器上计算文件摘要的值都是不同的,当浏览器上次访问服务器和这次访问的服务器不同的时候,ETag得到的值也就会不同,但是文件还是一样的。
[Last-Modified]的缺点: 系统上的文件有时内容不会改变,但是修改时间变了,又或者是某些文件修改非常频繁(毫秒级别),但是Last-Modified值记录的边界只是秒为单位,有可能照成文件不一样但是最后修改时间是“一样的”这种现象。
解决方法:两者同时使用,也是现在最常见的解决方案。服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
协商缓存的缺点:虽然协商成功后服务端只需要回复一个body为空的Response报文,但任然还需要发送Request请求与浏览器确认是否可以使用缓存,相对于强缓存更慢一些。
三、常见状态码
2XX系列:表示请求已经成功,成功的方式不同而已
200:表示请求成功,服务器也成功返回响应
3XX系列:表示需要重定向到其他位置
301:永久重定向,浏览器会记下来,下次访问会直接发请求到被重定向的新位置
302:临时重定向,只是这一次的请求被重定向了,下次还是会将请求,发送到旧的位置上
304:缓存重定向,表示缓存的内容没被改变,浏览器可以直接使用缓存
4XX系列:表示客户端错误
401:表示未授权,需要做用户验证
403:表示用户被禁止访问
404:表示用户请求的资源找不到
5XX系列:表示服务器错误
500:服务器处理请求过程中发生了错误
503:服务器暂时无法使用,可能是因为停机维护或者服务器超载
四、http报文
请求头部,编码后的格式:
GET / HTTP/1.1\r\nHost: localhost:3000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, sdch, br\r\nAccept-Language: zh-CN,zh;q=0.8\r\n\r\n
解码后的样子
request请求头部
GET / HTTP/1.1 使用get方法请求http服务器 路径是/ HTTP版本是1.1 (必要条件)
Host: localhost:3000 请求的主机地址和端口是 localhost:3000 (必要条件)
Connection: keep-alive 是否需要tcp的持久连接,keep-alive为持久连接 ,close为非持久连接
Cache-Control: max-age=0 当前没有缓存内容
Upgrade-Insecure-Requests: 1 告诉服务器可支持使用https不使用http的说明
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 当前浏览器使用版本,以及浏览器运行的环境
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 声明当前浏览器接收的MIME(多用户网络邮件扩展协议,其中包含各种超文本协议、多媒体协议等)类型
Accept-Encoding: gzip, deflate, sdch, br 声明当前浏览器可以支持的解码(解压缩)方式
Accept-Language: zh-CN,zh;q=0.8: 声明流量器所使用的语言,中文-简体中文,希望服务器返回中文的优先级是0.8
(分隔body的\r\n是必要条件,无论有否body 都需要带有才能识别请求)
response响应头部
HTTP/1.1 200 OK 响应头部最开始必须是声明协议版本HTTP/1.1 返回状态码 状态描述字符串(必要条件)
Date: Sat, 03 Mar 2018 05:09:34 GMT 返回后端在响应时的GMT的时间
Content-Type: text/html 返回body的MIME类型(必要条件,如果不返回,浏览器只能靠猜)
Content-Length: 14615 返回body的字节长度(必要条件)
Last-Modified: Sun, 11 Feb 2018 04:46:00 GMT 返回文件的最后修改的GMT时间,做缓存使用
Connection: Keep-Alive 是否需要tcp的持久连接,keep-alive为持久连接 ,close为非持久连接
Set-Cookie: BAIDUID=78D8AD1F7CE86739B74B83D25E4D0BDC: 返告诉客户端,当前用户在该域名的cookie值(持续对话使用的)
Server: BWS/1.1 服务器名字
Cache-control: no-cache 该页面不需要缓存
Accept-Ranges: bytes 服务器支持Range请求,该请求支持的单位是字节
(分隔body的\r\n是必要条件,无论有否body 都需要带有才能识别请求)
<html>.....<\html>