Http指超文本传输协议(HyperText Transfer Protocol)基于tcp/ip协议 是一种应用层协议
http历史
http0.9 1991 (早已淘汰)
- 只有GET方法
- 只有请求行
- 响应内容只有html字符串信息
- 请求完成立即断开tcp连接 不能持久连接
http1.0 1996 (非正式版本)
- 引入POST HEAD方法
- 引入请求头(文件类型,压缩方式,编码,字符集,语言等)请求体 响应头 响应体
- 支持更多的数据类型(文本,二进制文件,图片视频等)
- 支持持久连接多个请求复用一个tcp连接 但是非默认 需要手动设置Connection:keep-alive 只有部分浏览器支持
- 新增缓存策略Expires
- 新增状态码
- 新增UserAgent获取用户客户端信息(用户代理字符串)
缺陷
- 无状态 服务器不记录状态 可以使用cookie
- 无连接 默认非持久连接不能复用同一个tcp 浪费带宽
- 队头阻塞 基于请求->应答->请求->应答模型 只能等上一次响应之后才能发起下一次请求 如果上一次请求堵塞后面的请求也会跟着阻塞
http1.1 1999 (当前主流版本)
- 默认持久连接 Connection: close关闭
- 引入OPTIONS PUT DELETE TRACE CONNECT方法
- 引入host字段表示服务端域名 实现可以访问同一ip下不同虚拟主机下的网站
- 引入头域Range 可以指定获取部分服务端资源(1.0只能获取全部资源)返回码通常为206 常用于
分片下载 断点续传等 - 支持更多的缓存策略(Cache-Control)
- 尚不成熟的管道化技术(tcp一个连接可以并行发送多个请求,用content-length区分数据包,响应仍然按顺序返回,效果不明显)
缺陷
- 队头阻塞依旧存在
- 慢启动 避免启动占用过多资源 采取先慢后快策略
- 多个tcp竞争资源 网速不足时部分tcp会降速 重要要资源会和不重要的资源一起竞争资源
http2.0 2015
- 二进制协议
- h2是完全的二进制协议 完全使用二进制格式传输数据(h1头信息只能使用文本)
- 帧 消息 数据流
- 在tcp传输层和http应用层中间加入二进制分帧层 帧是h2中通信的最小单位 所有的请求/响应数据都被分割成更小的帧,帧采用二进制编码
- h2同域名下的所有请求都会复用一个tcp连接并且只会慢启动一次,该连接可以承载任意数量的双向数据流,每个数据流都有一个独一无二的编码id,数据流都以消息的形式发送,每个消息由多个数据帧组成,每个帧在请求时都必须加上数据流编码用以区分它属于哪个请求
- 多路复用
- h2在传输数据时会复用一个tcp连接,客户端和服务端可以同时乱序发送多个请求/响应数据帧,服务端解析时根据每个帧的数据流编码重新组装,解析完成再将响应数据拆分为多个数据帧响应客户端,浏览器再根据数据帧的编码将数据分发给对应的请求 多路复用解决了h1管道化导致的队头阻塞问题
- 头信息压缩
- 一方面使用gzip和compress对头信息进行压缩,另一方面将请求头和响应头使用同一个表进行维护,不必每次请求都携带头信息,节省开销
- 服务端推送
- 服务端可以将一些静态的资源推送给客户端 (websocket推送的是即时数据)
缺陷
- 只解决了请求应答模型队头阻塞问题,并没有解决tcp层面的队头阻塞问题
- tcp连接比较耗时
http3.0 2018+
- 弃用tcp 使用udp协议 基于udp实现类似h2多路复用的功能
- 使用quic协议解决udp丢包的问题
- udp相对于tcp只需要两次握手,并且不需要慢启动所以速度更快但是浏览器和系统目前支持度不够
https
https = http+ssl
http特点及其优缺点总结
- 简单灵活易扩展
- http协议比较简单 由头信息header+数据体body组成,头信息的字段语义化明显,开发者能自由修改
- 无状态
- 服务端不记录状态,优点是减少了资源的占用,缺点是需要用cookie去记录状态
- 明文传输
- 优点是方便调试,开发,缺点是不安全可以被监听和被窥探甚至被修改
- 性能
- http性能不差 但是仍有很大的提升空间
队头阻塞问题总结
- http0.9 过于古老 略
- http1.0 最多并行支持4个tcp连接 超出就会队头阻塞
- http1.1 最多并行支持6个tcp连接 超出就会队头阻塞 使用管道化技术时前一个请求被阻塞也会影响后面的请求
- http2.0 多路复用解决了队头阻塞,但是基于tcp的可以被监听和被窥探可以被监听和被窥探甚至被修改头阻塞问题仍然没有解决而且影响更大,因为同域名的请求会复用一个tcp并不会并行连接
- http3.0 基于udp quic协议解决队头阻塞
http基础
http报文组成结构
起始行(请求行/响应行) 描述请求或响应报文的基本信息头部信息(请求头/响应头) 使用key-value格式的字段详细描述报文信息空行用来分隔头信息和消息正文消息正文(请求体/响应体) 实际传输的数据 可以是二进制数据 图片 视频 文本等 起始行和头部信息统称为header,消息正文称为body 由空行分隔
http请求方法
GET
幂等请求(指发送多次和发送一次请求的效果相同)服务端资源不受影响比如请求网页资源- 浏览器一般
有缓存 查询字符串传参不安全参数直接放入url中请求长度有浏览器方面的限制参数只支持ASCⅡ字符
POST
非幂等请求服务端资源受影响比如账号注册- 浏览器一般
不缓存 请求体传参相对get安全- 发送两次请求 第一次为
预检资源询问服务器是否支持修改的请求头判断服务器是否为同源请求 是否支持跨域第二次为真正的post请求
PUT
发送数据更新资源不增加资源种类
DELETE
删除服务器资源
HEAD(了解)
- HEAD方法跟GET方法相同,只不过服务器响应时不会返回消息体。一个HEAD请求的响应中,HTTP头中包含的元信息应该和一个GET请求的响应消息相同。这种方法可以用来获取请求中隐含的元信息,而不用传输实体本身。也经常用来测试超链接的有效性、可用性和最近的修改。
OPTIONS
- 获取服务端所支持的所有请求方法
- 检查访问权限 一般用于跨域资源共享CORS 访问资源前发送嗅探请求是否允许跨域访问
CONNECT 网页用不到
- 与代理服务器建立隧道 进行tcp通信
TRACE 了解
- 支持该方式的服务器存在跨站脚本漏洞 一般用于测试和调试
常见的HTTP请求头和响应头
请求头
- User-Agent浏览器用户代理字符串
- Accept内容类型
- Accept-Language语言
- Accept-Charset字符集
- Accept-Encoding编码
- Cache-Control 缓存策略
- Connection连接状态
- Content-Type 文档类型
- Content-Length长度用于获取部分资源
- Host域
- Origin源
- Referer url
- Cookie
响应头
- Access-Control-Allow-Methods 允许的方法
- Access-Control-Allow-Origin 允许的源
- Access-Control-Max-Age 缓存过期时间
- Date 消息日期
- Server 服务器名称
- Connection
- Content-Type
http状态码
| 类别 | 定义 | 描述 |
|---|---|---|
| 1xx | Informational(信息性状态码) | 接受的请求正在处理 |
| 2xx | Success(成功状态码) | 请求正常处理完毕 |
| 3xx | Redirection(重定向状态码) | 需要进行附加操作来完成请求 |
| 4xx | Client Error (客户端错误状态码) | 服务器无法处理请求 |
| 5xx | Server Error(服务器错误状态码) | 服务器处理请求出错 |
常见的状态码:
1. 1xx Informational
1XX的状态码是在HTTP/1.1 中引入的,它们是信息性的状态码,是临时的,表示请求已被接受,需要继续处理。这些状态码并没有提供太多有用的信息,我们可能永远看不到1XX相关的状态码。
- 100 服务器已收到浏览器的请求标头,并且现在已准备好发送请求正文
- 102 服务器已经收到并正在处理请求,目前还没有响应
- 103 在服务器响应的HTTP消息之前返回一些响应头。该状态码用于允许用户代理预加载资源,同时服务器准备响应。
2xx
2xx 状态码表示客户端的请求被成功接收、理解和接受。
- 200 正常
- 204 正常 无响应体
- 206 正常 客户端进行范围请求 常用于断点续传,分片下载
3. 3xx Redirection
3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
- 301 Moved Permanently **永久重定向。**已为目标资源分配了一个新的永久 URI。新的 URI 会在 HTTP 响应头中的 Location 首部字段指定。若用户已经把原来的URI保存为书签,此时会按照 Location 中新的URI重新保存该书签。同时,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。
- 302 Found **临时重定向。**请求的资源被分配到了新的 URI,希望用户(本次)能使用新的 URI 访问资源。和 301 Moved Permanently 状态码相似,但是 302 代表的资源不是被永久重定向,只是临时性质的。也就是说已移动的资源对应的 URI 将来还有可能发生改变。
若用户把 URI 保存成书签,但不会像 301 状态码出现时那样去更新书签,而是仍旧保留返回 302 状态码的页面对应的 URI。同时,搜索引擎会抓取新的内容而保留旧的网址。因为服务器返回302代码,搜索引擎认为新的网址只是暂时的。
使用场景:
-
未登陆的用户访问用户中心重定向到登录页面。
-
访问404页面重新定向到首页。
-
304 Not Modified
浏览器缓存相关。该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关系。
带条件的请求(Http 条件请求):使用 Get方法 请求,请求报文中包含(if-match、if-none-match、if-modified-since、if-unmodified-since、if-range)中任意首部。
状态码304并不是一种错误,而是告诉客户端有缓存,直接使用缓存中的数据。返回页面的只有头部信息,是没有内容部分的,这样在一定程度上提高了网页的性能。
4. 4xx Client errors
-
400 Bad Request 请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
-
401 Unauthorized 发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。若之前已进行过一次请求,则表示用户认证失败。返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询(challenge)用户信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。
-
403 Forbidden 没有权限访问
-
404 Not Found 服务器上无法找到请求的资源
-
405 Method Not Allowed
服务器识别到浏览器使用的 HTTP 请求方法,但需要使用不同的方法才能提供所需的资源。服务器应该总是允许客户端使用 GET 和 HEAD 方法进行访问。 客户端可以通过 OPTIONS 方法(预检)来查看服务器允许的访问方法, 如下
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
复制代码
5. 5xx Server Error 服务端错误
- 500 内部服务器错误
- 502 无效网关
- 503 当前服务不可用
使用场景:
- 服务器停机维护时,主动用503响应请求;
- nginx 设置限速,超过限速,会返回503。
HTTP总结
连接方式
http1.0默认短连接 http1.1默认持久连接
缓存策略
1.0主要使用Expires和if-modified-since 1.1更多缓存策略 Cache-Control etag/if-none-match if-unModified-since if-match等
状态码
1.1更多的状态码
host
多域名部署提升速度
带宽优化
1.1引入range头域实现断点续传节省带宽
http相关面试题
HTTP状态码304是多好还是少好
-
服务端有缓存机制服务端判断客户端请求重复的资源就会返回304客户端接受304直接拿缓存中的数据而不必二次下载 -
304的好处是提高网站访问速度 频繁返回304不利于SEO 搜索引擎会优先爬取频繁更新的网站
HTTP1.0 和 HTTP1.1 区别
HTTP1.0
- 连接方式
默认非持久连接并行连接 多个TCP连接浏览器限制连接数量4个 如果请求数超过4个就会有队头阻塞问题 不支持断点续传浪费带宽客户端请求需要部分资源 服务端只会返回全部资源
HTTP1.1
- 连接方式
默认持久连接管道化连接多个http请求复用同一个TCP避免重复建立连接 请求头加入range头域 可以访问部分资源 返回码206常用于分段下载引入了更多的缓存策略(etag/if-none-match if-match if-Unmodified-since)增加host字段可以指定服务器域名 因为一台服务器可以有多个虚拟机所以可以有多个域名共享一个ip 这样就可以把请求发送到同一服务器的不同网站增加更多请求方法 PUT OPTIONS HEAD等
HTTP1.1 和 HTTP2.0 区别
-
二进制
http2 使用二进制协议 数据体和报文头都可以是二进制http1.1 报文头只能是文本 数据体可以是文本或者二进制
-
多路复用
使用数据流概念 数据包不会按照顺序发送 同一个连接中有多个数据包 数据包可能属于不同的请求 通过给数据包做标记来判断属于哪个请求同一请求的所有数据包为一个数据流 每个数据流都有唯一编码 数据包发送时会标记数据流id 用来区分它属于哪个数据流
-
服务端推送
HTTP/2 允许服务器未经请求,主动向客户端发送资源
-
头信息压缩
http1.1协议不带状态,每次请求都会带上所有信息,包括一些重复的比如COOKIE UserAgent 浪费带宽http2引入了头信息压缩机制 头信息使用 gzip 或 compress 压缩后再发送 客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了
队头堵塞问题
-
原因: http请求根据请求-应答模型 形成一个先入先出的队列 请求无优先级只会根据顺序依次请求 如果队首的请求耗时较长 就会造成队头阻塞 后面的请求也会一直等着
-
解决:
- 并发连接 对于一个域名允许多个长连接,增加任务队列
- 域名分片:将域名分出很多二级域名,它们都指向同样的一台服务器,能够并发的长连接数变多
- h2的多路复用
HTTP和HTTPS协议的区别
- 安全性:https使用SSL加密传输更安全 http超文本传输协议 明文传输
- 认证: https需要CA证书 费用较高 http不用
- 连接方式不同 端口也不同 http80 https443
- http无状态 https可以加密传输 身份认证
页面有多张图片,HTTP是怎样的加载表现?
HTTP1 TCP连接数最大为6 会请求多次 通过多域名部署可以解决
HTTP2 使用多路复用可以一个tcp同时发送多个请求 会瞬间加载出大量资源