一、网络基础 TCP | IP
通常使用的网络是在 TCP | IP 协议族的基础上运作的,而 HTTP 属于其中的一个子集
- 协议:通信,双方必须基于相同的方法,比如如何探测到通信目标、由哪一边先发起通信、使用哪种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信等。
- TCP | IP:是在IP协议的通信过程中,使用到的协议族的统称
- TCP | IP 分层:
- 应用层:FTP | DNS | HTTP | websocket
- 传输层:提供可靠的字节流服务,如TCP | UDP
- 网络层:在众多的选项中选择一条传输路线,如 IP
- 数据链路层:网络硬件部分,包括控制操作系统、硬件的设备驱动、网卡、光纤
1、IP协议
负责把各种数据包传送给对方
- IP地址:指明了节点被分配到的地址
- MAC地址:指网卡所属的固定地址
- ARP:是一种用以解析地址的协议,根据通信方的IP地址就可以反查出对应的MAC地址
2、TCP
采用三次握手准确无误地将数据送达目标处
- SYN(synchronize)
- ACK(acknowledgement)
3、UDP
- UDP是无连接的
- TCP保证数据正确性,UDP可能丢包
- TCP保证数据顺序,UDP不保证
- TCP连接只能是点到点的,UDP支持一对一,一对多,多对一和多对多的交互通信
4、DNS
提供域名到IP地址之间的解析服务,或逆向从IP地址反查域名的服务
5、URI 和 URL
URI:Uniform Resource Identifier, 统一资源标识符,用字符串标识某一互联网资源
URL:Uniform Resource Locator,统一资源定位符,表示资源的地点(互联网上所处的位置)
URL 是 URI 的子集
http://user:pass@www.example.com:80/dir/index.html?uid=1#ch1
协议方案名 + 登录信息(认证)+ 服务器地址 + 服务器端口号 + 带层次的文件路径 + 查询字符串 + 片段标识符
二、HTTP协议格式
1、HTTP请求协议格式
<request line> // http请求行,用来说明请求类型(method)、要访问的资源(request-URI)以及使用的HTTP版本
<headers> // http请求消息报头,说明服务器要使用的附加信息
<blank line> // 回车换行
[<request-body>] // http请求正文
复制代码
POST /index.html HTTP/1.1 # 请求报文
Host: hackr.jp # 请求首部字段
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 16
If-Modified_Since:Thu, 12Jul 2012 07:30:00 GMT # 仅返回2012年7月12日7点30分以后更新过的index.html页面资源,如果未有内容更新,则以304 Not Modified作为响应返回
name=ueno&age=37 # 内容实体
复制代码
2、HTTP响应协议格式
<status line> // http响应状态行,通过提供一个状态码(status code)来说明所请求的资源情况。及原因短语(reason-phrase)
<headers> // http响应消息报头
<blank line> // 回车换行
[<response-body>] // http响应正文
复制代码
HTTP/1.1 200 OK # 协议版本 + 状态码 + 用以解释状态码的原因短语
Date: Tue, 10 Jul 2012 06:50:15 GMT # 可选的响应首部字段
Content-Length: 362
Content-Type: text/html
<html> # 资源实体的主体(entity-body)
复制代码
三、HTTP 方法
1、GET
获取资源。GET提交的数据会在地址栏中显示出来。特定浏览器和服务器对URL长度有限制,例如 IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。因此对于GET提交时,传输数据就会受到URL长度的限制。
2、POST
传输实体主体。由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3、PUT
用于传输文件,由于不带验证机制,存在安全性问题。若配合Web应用程序的验证机制,或架构设计采用REST(REpresentational State Transfer, 表征状态转移)标准的同类Web网站,可能会开放使用PUT方法。
4、HEAD
和GET方法一样,只是不返回报文主体部分,用于确认URI的有效性及资源更新的日期时间等
5、DELETE
用于删除文件,和PUT一样不带验证机制
6、OPTIONS
用来查询针对请求URI指定的资源支持的方法:Allow: GET, POST, HEAD, OPTIONS
如果不是访问特定资源而是对服务器本身发起请求,可以用一个*
来代替请求URL
OPTIONS * HTTP/1.1
7、TRACE
让服务器将之前的请求通信环回给客户端的方法,客户端通过该方法可以查询发送出去的请求是怎样被加工/篡改的。容易引发XST(Cross-Site Tracing)攻击
8、CONNECT
要求用隧道协议连接代理,主要使用SSL|TLS把通信内容加密后经网络隧道传输
- SSL: 安全套接层 Secure Sockets Layer
- TLS:传输层安全 Transport Layer Security
CONNECT 代理服务器名:端口号 HTTP版本
复制代码
四、HTTP 状态码
1. 状态码类别
- 1XX: 信息性状体码 接收的请求正在处理
- 2XX: 成功状态码 请求正常处理完毕
- 3XX: 重定向状态码 需要进行附加操作以完成请求
- 4XX: 客户端错误状态码 服务器无法处理请求
- 5XX: 服务器错误状态码 服务器处理请求出错
2. 14种常见状态码
当返回301、302、303,几乎所有的浏览器都会把POST改为GET,并删除请求报文内的主体,之后请求会自动重新发送
- 200 OK: 请求被正常处理
- 204 NO Content: 请求处理成功,但无资源可返回;在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用
- 206 Partial Content: 成功处理范围请求
- 301 Moved Permanently: 永久性重定向,表示请求的资源已被分配了新的URI。当指定资源路径的最后忘记添加‘/’,就会返回该状态码
- 302 Found:临时性重定向,表示请求的资源存在另一个URI;当替代303使用时,表示客户端应当采用GET方法获取资源
- 304 NOT Modified: 允许请求访问资源,但未满足条件(指请求首部包含If-Match,If-Modified-Since,If-None-Match, If-Range,If-Unmodified-Since),响应不包含任何响应的主体部分。和重定向没有关系
- 400 Bad Request: 请求报文中存在语法错误,需修改请求内容后再次发送请求
- 401 Unauthorized: 表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询(challenge)用户信息
- 403 Forbidden: 不允许访问那个资源
- 404 Not Found: 服务器上没有请求的资源。也可以在服务器端拒绝请求且不想说明理由时使用
- 500 Internal Server Error: 服务器端在执行请求时发生了错误
- 503 Service Unavailable: 表明服务器暂时处于超负载或正在进行停机维护,无法处理请求。最好写入Retry-After首部字段再返回给客户端
五、HTTP 首部
若首部字段重复了,根据浏览器内部处理逻辑的不同,结果可能不一致。有些会优先处理第一次出现的首部字段,有些则会优先处理最后出现的首部字段。
HTTP 要确保它的报文被正确传送、识别、提取以及适当处理:
- 可以被正确地识别(通过Content-Type首部说明媒体格式,Content-Language首部说明语言),以便浏览器和其他客户端能正确处理内容
- 可以被正确的解包(通过Content-Length首部和Content-Encoding首部)
- 是最新的(通过实体验证码和缓存过期控制)
- 符合用户的需要(基于Accept系列的内容协商首部)
- 在网络上可以快速有效地传输(通过范围请求、差异编码以及其他数据压缩方法)
- 完整到达、未被篡改(通过传输编码首部和Content-MD5校验和首部)
报文是箱子,实体是货物
1. 通用首部字段
- Cache-Control: 控制缓存的行为
- Connection:逐跳首部、连接的管理
- Date:创建报文的日期时间
- Pragma:报文指令
- Trailer:报文末端的首部一览
- Transfer-Encoding:指定报文主体的传输编码方式
- Upgrade:升级为其他协议
- Via:代理服务器的相关信息
- Warning:错误通知
2. 请求首部字段
- Accept: 用户代理可处理的媒体类型
- Accept-Charset: 优先的字符集
- Accept-Encoding: 优先的内容编码
- Accept-Language: 优先的语言(自然语言)
- Authorization: Web认证信息
- Expect: 期待服务器的特定行为
- From: 用户的电子邮箱地址
- Host: 请求资源所在服务器
- If-Match: 比较实体标记(ETag)
- If-None-Match: 比较实体标记
- If-Modified-Since(IMS请求): 比较资源的更新时间
- If-Unmodified-Since: 比较资源的更新时间
- If-Range: 资源未更新时发送实体Byte的范围请求
- Max-Forwards: 最大传输逐跳数
- Proxy-Authorization: 代理服务器要求客户端的认证信息
- Range: 实体的字节范围请求
- Referer: 对请求中URI的原始获取方
- TE: 传输编码的优先级
- User-Agent: HTTP客户端程序的信息
3. 响应首部字段
- Accept-Ranges: 是否接受字节范围请求
- Age: 推算资源创建经过时间
- ETag: 资源的匹配信息
- Location: 令客户端重定向至指定URI
- Proxy-Authenticate: 代理服务器对客户端的认证信息
- Retry-After: 对再次发起请求的时机要求
- Server: HTTP服务器的安装信息
- Vary: 代理服务器缓存的管理信息
- WWW-Authenticate: 服务器对客户端的认证信息
- Last-Modified: 最后修改日期
4、实体首部字段
- Allow: 资源可支持的HTTP方法
- Content-Encoding: 实体主体适用的编码方式
- Content-Language: 实体主体的自然语言
- Content-Length: 实体主体的大小
- 对缓存代理服务器尤其重要,如果缓存服务器收到被截尾的报文却没有识别出截尾的话,它可能会存储不完整的内容并多次使用它来提供服务。缓存代理服务器通常不会为没有显式Content-Length首部的HTTP主体做缓存,以此来减小缓存已截尾报文的风险。
- 持久连接:因为连接是持久的,客户端无法依赖连接关闭来判断报文的结束。通过该首部就可以知道报文从何处开始,从何处结束。
- 如果编码了,则显示的是编码后的主体字节长度。
- Content-Location: 替代对应资源的URI
- Content-MD5: 实体主体的报文摘要
- 发送方可以在生成初始的主体时,生成一个数据的校验和,这样接收方就可以通过检查这个校验和来捕获所有意外的实体修改
- 当作散列表的关键字,用来快速定位文档并消除不必要的重复内容存储
- 如果编码了,针对编码后的文档
- Content-Range: 实体主体的位置范围
- Content-Type: 实体主体的媒体类型(MIME类型)
- 主媒体类型/子类型
- 编码之前的实体主体类型
- 支持可选的参数进一步说明内容的类型
- Expires: 实体主体过期的日期时间
- Last-Modified: 资源的最后修改日期时间
- ETag: 这份文档特定实例的唯一验证码
- Cache-Control: 应该如何缓存该文档
5、RFC4229 HTTP Header Field Registrations
- Cookie: 请求首部字段,服务器接收到的Cookie信息
- Set-Cookie: 响应首部字段,开始状态管理所使用的Cookie信息
- NAME=VALUE:赋予Cookie的名称和值
- expires=DATE: Cookie的有效期
- path=PATH: 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为创建Cookie的服务器的域名)
- domain=域名: 作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器的域名)
- Secure: 仅在HTTPS安全通信时才会发送Cookie
- HttpOnly: 加以限制,使Cookie不能被JavaScript脚本访问
- 使用JS的document.cookie无法读取附加该属性后的
- Content-Disposition
6、逐跳首部(Hop-by-hop Header)
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
7、端到端首部(End-to-end Header)
除了8个逐跳首部外,其他所有字段都属于端到端首部
8、其他首部字段:HTTP首部字段是可以自行拓展的
- X-Frame-Options:防止点击劫持攻击
- DENY: 拒绝
- SAMEORIGIN:仅同源域名下的页面匹配时许可
- X-XSS-Protection:防止跨站脚本攻击,用于控制浏览器XSS防护机制的开关
- 0: 将XSS过滤设置成无效状态
- 1: 将XSS过滤设置成有效状态
- DNT:拒绝个人信息被收集
六、HTTP 的缺点
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
七、HTTPS
HTTPS = 数据加密 + 网站认证 + 完整性验证 + HTTP
- 通过证书等信息确认网站的真实性
- 建立加密的信息通道
- 数据内容的完整性
CA中心发布的数字证书通过对称加密和非对称加密对我们网上传输的信息进行加密。端口号:443
- 对称加密:加密和解密使用同一个密钥
- 非对称加密:
- 公钥加密:发给查看网站的所有人
- 私钥解密:只有网站服务器自己拥有
八、HTTP 2.0 的优势
-
采用二进制格式传输数据,而非 HTTP1.1 的文本格式,二进制格式在协议的解析和优化拓展上带来更多的优势和可能;
-
对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络流量,而 HTTP1.1 每次都会携带大量冗余头信息,浪费带宽,头压缩能够很好的解决该问题;
-
多路复用,就是多个请求都通过一个 TCP 连接并发完成,HTTP1.1 虽然通过 pipeline 也能并发请求,但是多个请求之间的响应会被阻塞的,所以 pipeline 至今也没有被普及应用,而 HTTP2.0 做到了真正的并发请求,同时,流还支持优先级和流量控制;
-
Server Push, 服务端能够更快的把资源推送给客户端,例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML; 再发送这些请求,当客户端需要的时候,它已经在客户端了。
九、WebSocket
websocket 是 HTML5 提出的一套补缺 HTTP 链接中不能持久链接的协议。
HTTP协议建立的“长连接”是“伪长连接”,只是靠服务器不断循环实现了所谓的长连接效果。在连接后的过程中,服务器都会不停的链接与断开,数据头信息不停重复的发送,浪费宽带,信息交换的效率低下。
websocket服务器主动推送,只要有数据就推送到请求方。
-
WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用。
-
WS的连接不能通过中间人来转发,它必须是一个直接连接。
-
WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
-
WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息。
-
WS的数据帧有序
基于 Node.js 编写的一个 Socket.IO 是一个开源实现WebSocket的库,它通过node.js实现服务端的同时,也提供了客户端js库,socket.io支持事件触发为基础进行的双向数据通信
十、面试题
Etag 的值是服务端对文件的索引节、大小和最后修改时间进行 Hash 后得到的
有了 Last-Modified, 为什么还要用 Etag?
- 如果在1S之内对一个文件进行两次更改,Last-Modified 就会不正确
- 某些服务器不能精确的得到文件的最后修改时间
- 一些文件也许会周期性的更改,但是内容并没有改变(仅仅改变的是修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET
- 即有时候 Etag 可以弥补 Last-Modified 的判断缺陷
有了 Etag, 为什么还要用 Last-Modified?
- 有时候 Last-Modified 可以弥补 ETag 判断的缺陷,比如一些图片等静态文件的修改,如果每次扫描内容都生成 ETag 来比较,显然要比直接比较修改时间慢很多。