再来对http协议做个详细认识
一、简介:
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)的协议。
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
二、主要特点:
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。随着时间的推移,网页变得越来越复杂,里面可能嵌入了很多图片,这时候每次访问图片都需要建立一次 TCP 连接就显得很低效.
Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接 - 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
- 支持B/S及C/S模式。
1、URI
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个URI来定位的.
URI一般由三部组成:
- 访问资源的命名机制
- 存放资源的主机名
- 资源自身的名称,由路径表示,着重强调于资源。
2、URN
URN,uniform resource name,统一资源命名,是通过名字来标识资源,比如mailto:itesting@awsome.com。
3、URL
URL全称是UniformResourceLocator, 中文叫统一资源定位符。是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。互联网上用URL来标识某一处资源的地址,主要用在各种WWW客户程序和服务器程序上.
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成:
- 协议(或称为服务方式)
- 存有该资源的主机IP地址(有时也包括端口号)
- 主机资源的具体地址。如目录和文件名等
三者关系
URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL.
4、URL的组成部分及其含义:
以下面这个URL为例
一个完整的URL包括以下几部分:
- 协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在"HTTP"后面的“//”为分隔符。
- 域名部分:该URL的域名部分为“www.xxx.com”。一个URL中,也可以使用IP地址作为域名使用
- 端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
- 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/profile/”
- 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.aspx”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
- 锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
- 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“id=5&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
三、HTTP请求方法
1、http请求由三部分组成,分别是:请求行、消息报头、请求正文
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本
格式:Method Request-URI HTTP-Version CRLF
- Method表示请求方法;
- Request-URI是一个统一资源标识符;
- HTTP-Version表示请求的HTTP协议版本;
- CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF符)。
举例:
GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,
eg:GET /form.html HTTP/1.1 (CRLF)。
2、HTTP请求方法(所有方法全为大写)有多种,各个方法的解释如下:
- GET 请求获取Request-URI所标识的资源
- POST 在Request-URI所标识的资源后附加新的数据
- HEAD 请求获取由Request-URI所标识的资源的响应消息报头
- PUT 请求服务器存储一个资源,并用Request-URI作为其标识
- DELETE 请求服务器删除Request-URI所标识的资源
- TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
- CONNECT 保留将来使用
- OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
常用的是GET, POST, PUT, DELETE
那这四种方法除语义外有什么其他区别呢?
首先介绍两个概念:安全性和幂等性。
如果针对一个URL的方法不改变URL所指资源的状态,就称其为安全的,显然在这四种方法里,只有GET方法是安全的。
幂等性,来源于数学上的术语,即对同一操作数的多次操作与一次操作效果是一样的操作符即称幂等操作符,比如取绝对值操作符。类比到网络操作中就是指一方法对同一URL的请求,多次和一次的效果是一致的,就称该方法是幂等的,显然除POST外其他三种方法都是幂等的,总结如下表:
http方法 | 安全 | 幂等 |
---|---|---|
GET | 是 | 是 |
POST | 否 | 否 |
PUT | 否 | 否 |
DELETE | 否 | 否 |
另外在具体技术实现上,这四种方法也有一些区别,那么POST与GET有什么区别呢?
- 使用目标不同:
POST与GET都用于获取信息,但是GET方式仅仅是查询,并不对服务器上的内容产生任何作用结果;每次GET的内容都是相同的。
POST则常用于发送一定的内容进行某些修改操作。 - 大小不同:
由于不同的浏览器对URL的长度大小有一定的字符限制,因此由于GET方式放在URL的首部中,自然也跟着首先,但是具体的大小要依浏览器而定。
POST方式则是把内容放在报文内容中,因此只要报文的内容没有限制,它的大小就没有限制。 - 安全性不同:
GET是直接添加到URL后面的,直接就可以在URL中看到内容。
而POST是放在报文内部的,用户无法直接看到。
3、HTTP报文常见属性
chrome打开上面的link,按F12
- URL, 即http访问的地址
- request method, 报文的请求方式
- status code, 状态码以及状态短语
- Accept Encoding, 内容编码
- Connection, 连接方式
- Cookie, 添加的cookie内容
- Host, 目标主机
- User-Agent, 客户端浏览器的相关信息
- Set-Cookie, 指定想要在Cookie中保存的内容
4、HTTP是无状态的,如何保存状态?
由于http是一种无状态的协议,因此无论是客户端还是服务器都不记录http的相关信息。这样设计一方面减轻了服务器端的负载,另一方面减小了http请求的开销。
但是针对某些特殊的场景,需要时刻记录用户的相关信息,这该如何处理呢?
5、cookie
客户端第一次访问,服务器在http响应头中添加Set-Cookie信息,其值的格式通常是name = value的格式。浏览器收到响应后会根据头中的字段保存cookie,下一次访问时在请求头中附带cookie内容,供服务器根据cookie值进行后续处理。
cookie的内容主要包括:名字,值,过期时间,路径和域。
cookie机制采用的是在客户端保持状态的方案。
与 cookie 相对的一个解决方案是 session:
6、session
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,
服务器首先检查这个客户端的请求里是否已包含了一个session标识- 称为session id,
如果已包含一个session id则说明以前已经为此客户端创建过session,
服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),
如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,
session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie(一般这个cookie的名字都是类似于SEEESIONID),
这样浏览器下次发请求的时候,这个session id会被放置在请求头中,和cookie一起发送回来。
服务器再通过内存中保存的session id跟cookie中保存的ssession id进行比较,并根据id在内存中找到之前创建的session对象,提供给请求使用,
也就是服务器会通过session保存一个状态记录,浏览器会通过cookie保存状态记录,
服务器通过两者的对比实现跟踪状态,这样的做,也极大的避免了cookie被篡改而带来的安全性问题。
7、URL重写
由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。
附加方式:
- 作为URL路径的附加信息,表现形式为:
http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764 - 作为查询字符串附加在URL后面,表现形式为:
http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。
8、cookie和session的区别:
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。 - cookie只能保存字符串类型,以文本的方式。session通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象)
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。Session大小没限制。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。 - Session生成的Session id是在cookie里保存的,cookie被禁止后可以通过URL重写来继续使用session
- session会给服务器带来压力,考虑到服务器性能,应当使用COOKIE。
- 所以建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
9、Token 和Session区别
- Token放客户端, Session在服务端。
- Session是空间换时间, Token是时间换空间。
- Token解决了集群时候跨节点访问问题。
Cookie有限制,每次请求服务端必须带上,还有大小不能超过4kb,如果想突破这个限制怎么办?
10、WebStorage
为克服由cookie所带来的一些限制,当数据无需发回服务器时使用。
1、WebStorage两个主要目标:
- 提供一种在cookie之外存储会话数据的路径。
- 提供一种存储大量可以跨会话存在的数据的机制。
2、HTML5的WebStorage提供了两种API:
- localStorage(本地存储)
- sessionStorage(会话存储
这两种区别在哪里?
1、生命周期:
localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。
sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
2、存储大小:
localStorage和sessionStorage的存储数据大小一般都是:5MB
3、存储位置:
localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信。
4、存储内容类型:
localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理。
5、应用场景:
localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。sessionStorage:敏感账号一次性登录;
Web Storage带来的好处:
- 减少网络流量:
一旦数据保存在本地之后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要的来回传递 。 - 快速显示数据:
性能好,从本地读数据比通过网络从服务器上获得数据快得多,本地数据可以及时获得,再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示 。 - 临时存储:
很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便。
注意:WebStorage这部分内容copy自网络,原创不可考。
四、HTTP状态码
1、状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
- 1xx:指示信息--表示请求已接收,继续处理
- 2xx:成功--表示请求已被成功接收、理解、接受
- 3xx:重定向--要完成请求必须进行更进一步的操作
- 4xx:客户端错误--请求有语法错误或请求无法实现
- 5xx:服务器端错误--服务器未能实现合法的请求
2、常见状态码:
-
200 OK //客户端请求成功
-
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
-
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
-
403 Forbidden //服务器收到请求,但是拒绝提供服务
-
404 Not Found //请求资源不存在,eg:输入了错误的URL
-
500 Internal Server Error //服务器发生不可预期的错误
-
503 Server Unavailable //服务器当前不能处理客户端的请求
五、相关问题
- HTTP协议是有状态的还是无状态的?
- HTTP协议如何保持状态?
- 有了cookie为什么还要session?
- 不要cookie行不行?能答出URL重写的已经不错了
- session保存在服务器内存中,随着用户的增多,服务器撑不住了怎么办?
- 假设我使用了集群服务怎么办?这个时候聪明点的就会答sesion sticky, 或者使用Memcached集中所有session id了
- session 服务器挂了怎么办? 再弄个集群,有点傻吧,自然的,Token就被带出来了。然后再问Token一般怎么生成的啊?
- Token一般怎么生成的啊?服务器生成,把user id+时间+私密签名用Base64加密生成,自己保存一份(不放内存放DB, 也可以不保存,那么收到客户端id就用加密算法再算一次生成token来对比), 发给客户端一份。
- token里能不能保存敏感信息啊?为什么?
- Base64是加密吗?,为什么?
- 什么是JWTtoken啊? token组成里的私密签名,是用什么加密的啊,顺便就把公钥私钥给理清楚了,对称算法,非对称算法也给考察了
- HTTP和HTTPS的核心区别是什么?能答出TCP请求并说出区别是SSL协议的你就收了吧,像什么get和post的区别,生成一个TCP请求包还是2个就不必要再纠结了, 能研究到这里的,测试肯定也能干好。
以上内容摘自【iTesting】公众号中的 HTTP协议总结