HTTP

202 阅读55分钟

http

web网络基础

使用http协议访问web

  • 在浏览器上输入url,然后会展示页面
  • 实际上是向服务器发送了一个请求,服务器根据路径等参数,返回了相应的内容
  • 所以web是建立在http基础上的,页面的展示以及大多数的交互渲染,除了依赖于js外,大多也都依赖于http请求

web发展史

  • 1990年11月,CERN研发了世界上第一台web服务器和web浏览器
  • 1993年1月,美国的浏览器NCSA问世,这时候已经可以展示html图像了
  • 1994年12月,网景发布了Netspcape Navigator 1.0
  • 1995年微软发布Internet Explorer1.0和2.0,随后,html2.0发布
  • 1995年,微软和网景开始了浏览器大战,他们分别对各自浏览器进行拓展,而且也没有规则限制,所以后续编写html的时候需要考虑他们的兼容性
  • 2000年,网景衰落,2004年,Mozilla基金会发布Firefox浏览器

驻足不前的HTTP

  • 于1990年问世,这时候http并没有作为正式的标准被建立,1.0之前的所有版本可以理解为0.9版本
  • HTTP于1996年5月被正式作为标准发布,版本被命名为HTTP1.0
  • HTTP1.1于1997年1月发布,是目前主流的http协议版本

TCP/IP

  • 计算机与网络设备相互通信,双方需要有一些相同的规则,如谁先发起起通信,不同的设备怎么通信,怎么结束通信等等,这些规则就是协议
  • TCP/IP分为4层,应用层、传输层、网络层、链路层

应用层

  • 应用层决定了向用户提供应用服务时通信的活动
  • 应用层包含了多种服务,如:FTP协议(文件传输协议)、DNS(域名查询系统)、HTTP协议等

传输层

  • 传输层对上层应用层提供处于网络连接中,双方的数据传输
  • 传输层有两个性质的不同协议:TCP(传输控制协议)、UDP(用户数据报协议)

网络层

  • 网络层用来处理在网络上流动的数据包(网络传输的最小单位)
  • 规定了通过怎样的传输路径把数据包传递给对方

链路层

  • 用来处理连接网络的硬件层,如:设备、网卡、光纤等物理部分
  • 硬件统归链路层

TCP/IP通信传输流

  • 传输顺序:客户端应用层(HTTP协议)、客户端传输层(TCP协议)、客户端网络层(IP协议)、客户端链路层(硬件媒介)、服务器链路层、服务器网络层(IP协议)、服务器传输层(TCP协议)、服务器应用层(HTTP协议)
  • 可以理解为走了一个U型,客户端自顶向下,然后服务端自底向上,当返回响应的时候,就变成服务端自顶向下,客户端自底向上
  • 以发送举例:客户端在应用层发送了http请求,到传输层的时候,TCP协议将应用层接收到的数据(HTTP请求报文)进行分割、添加信息(标记序号、端口号等),然后转发给网络层、在网络层(IP协议)增加作为通信目的地的MAC地址(网卡所属固定位置,几乎不会改变)然后转发给链路层,然后服务端在链路层接收到数据,一层层的向上发送,直到应用层拿到数据
  • 发送的时候,每经过客户端的一层,就会在请求头上增加该层的信息,到服务端接收的时候,每经过一层会消除一层客户端对应层的信息,这个过程称为封装

IP协议

  • TCP/IP的IP指的不是ip地址,而是IP协议
  • IP协议处于网络层,负责将各种数据包传递给对方。为了确保可以传递到对方那里,需要满足各种条件,最重要的两个条件是IP地址和MAC地址
  • IP地址是节点被分配的地址,MAC地址(Media Access Control Address)是指网卡所属的固定位置,IP地址可以和Mac地址进行配对,IP地址可以变换,但Mac地址基本上不会改变
Mac地址
  • baike.baidu.com/item/MAC%E5…
  • 可以看到已经多次提到了Mac地址这个字眼,Mac地址是物理机地址,代表的是当前设备的唯一网络标识
  • ip之间的通信依赖于Mac地址,通常情况下,通信的双方是不在同一个局域网内的,所以需要经过多台计算机和网络设备的中转才能连接到对方,在中转的时候会利用下一站中转设备的Mac地址来搜索下一个中转目标,这时候会用到ARP协议,ARP协议是一种可以解析地址的协议,根据通信双方的IP地址就可以查出对应的Mac地址

TCP协议

  • TCP协议位于传输层,作用是提供可靠的字节流服务。
  • 上面有提到是在传输的时候会把数据进行分割,所谓的字节流服务,就是TCP为了方便传输,在数据过大时,将数据分割成以报文段为单位的数据包
  • 那既然分段了,那就需要组合,所以就需要他的可靠性
  • 为了可以确保将数据送到目标处,TCP采用了三次握手策略
TCP三次握手
  • 发送端发送一个带有SYN标志的数据包给对方,用来确定对方身份
  • 接收端接收到后,返回一个带有SYN/ACK标志的数据包,表示确认信息
  • 发送端接收到后发送一个ACK数据包给对方,表示ok
  • 三次握手的目的:确认通信双方的接受能力和发送能力是否正常,为后续传输做准备
  • 以小明找对象举例子:
    • 小明向小红说:我喜欢你。
    • 小红接收到,返回:小明啊,我也喜欢你,处对象吧。
    • 小明接收到跟小红说:好。 这时候就建立关系了
四次挥手
  • 因为TCP是全双工的,所以连接双方需要单独进行关闭
    • 1.客户端向服务端发送FIN码,这时客户端已停止再次发送数据,进入等待关闭状态,需要服务端确认
    • 2.服务器收到后,返回一个ACK码,表示已经收到客户端信息了,这个时候客户端的通道关闭了,服务端进入等待关闭状态,所以也可以称作半关闭状态
    • 3.服务端向客户端发送FIN码
    • 4.客户端返回ACK码,服务端关闭通道,四次挥手完成
    • 以小明和小红分手举例子:
      • 小明跟小红说:你要不哄我,就分手。
      • 小红返回:我就不,分手吧。
      • 然后小红不相信,跟小明说:你真要分手?
      • 小明返回:对。小明收到后就相信了。这时关系就可以断啦。

DNS服务

  • DNS服务属于应用层协议,它提供了域名到ip之间的解析服务
  • 相对ip一堆数字来说,域名的形式更好记忆,比如京东的jd.com,但是计算机理解不了
  • 发送端拿到域名后,请求DNS服务器,然后DNS服务器返回对应ip,发送端拿到ip再向ip发送http请求

串一下上面的内容

  • 客户在浏览器上输入了一个url,然后回车
  • 客户端会请求DNS服务器,查找对应ip,然后DNS查找到后返回给客户端
  • 客户端拿到ip,在应用层向ip发送请求
  • 在传输层TCP协议对请求报文分段进行处理,然后为了保证信息的完整性和可靠性,采用TCP三次握手建立连接
  • 然后在网络层IP协议来查询对方的物理地址,在查询过程中发现需要中转好多次,然后使用ARP协议来协助查找
  • 在链路层,传输
  • 等服务端返回完成后,进行四次挥手断开连接

URI和URL

  • URI 统一资源标识符
  • URL 统一资源定位符
  • URL是URI的子集,但却又没有分的那么细致

URI(Uniform Resource Identifier)

  • 由某个协议方案表示的协议的定位标识符。协议方案指的是访问资源时使用的协议类型,如http、file
  • Uniform 规定统一的格式,可以处理多种不同的资源类型,不需要根据上下文环境来识别访问方式。
  • Resource 资源,可标识的任何东西,如图像、文档等
  • Identifier 科表示的对象,也成为标识符

简单的http协议

  • HTTP协议规定:在一次通信中,一定会有一个客户端和服务端,客户端发送请求,服务端响应
//请求
GET /index.html /HTTP/1.1
Host: hackr.jp

//响应
HTTP/1.1 200 OK
Date Tue, 10 Jul 2012 065015 GET
Content-Length:362
Content-Type: text/html

<html>
.....
<html>
  • 其中GET是请求类型,后面的/index.html是访问资源路径(请求URI),HTTP/1.1是http的版本号,用来提示客户端使用的HTTP协议功能,Host是域名,也可以为ip
  • 请求报文由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成
  • 200是状态码,OK是状态码的原因短语, Date表示创建响应的时间,下面就是一些描述,然后以一个空行隔开,再下面就是响应体

请求类型

  • 类型要使用大写

GET

  • 将参数放在url上,通常用作获取内容

POST

  • 将参数放在响应体内,相对好看且安全些,通常用作上传信息

PUT

  • 与POST一致,语义化些许不同,常用于新增

HEAD

  • 与GET相同,但是不返回报文主体,用来确认URI的有效性和更新时间,和通信状态

DELETE

  • 与GET相同,语义化些许不同,常用来删除文件

OPTIONS

  • 用来查询对方支持的请求方法
//请求
OPTIONS * HTTP/1.1
Host : ........

//响应
HTTP/1.1 200 OK
Allow: GET,POST,HEAD,OPTIONS

CONNECT

  • 在与代理服务器通信时,建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接层)和TLS(传输层安全)协议把通信内容加密后经网络隧道传输
//请求
CONNECT 代理服务器名:端口号 HTTP版本
Host: 服务器

//响应 之后进入网络隧道
HTTP/1.1 200 OK 

版本支持请求类型

类型说明支持的HTTP版本
GET获取资源1.0、1.1
POST传输资源1.0、1.1
PUT传输资源1.0、1.1
HEAD获得报文首部1.0、1.1
DELETE删除文件1.0、1.1
OPTIONS询问支持的请求类型1.1
TRACE追踪路径1.1
LINK建立和资源之间的联系1.0
UNLINK断开连接关系1.0

HTTP是不保存状态的协议

  • HTTP是一种不保存的状态,也就是无状态,HTTP协议本身不对请求和响应之间的通信状态进行保存。在HTTP这个级别,协议对于发送过来的请求或响应都没有做持久化处理。
  • 也就是说,在进行http通信的时候,每当有新的请求产生,就会有新的响应产生。
  • 这样会造成一定业务上的问题,比如说因状态无法保留,导致用户一直处于登录页面,无法进行购物
  • 我们可以用浏览器存储或cookie来解决这一问题

持久连接节省通信量

  • HTTP协议初始版本每次进行一次HTTP通信就要重新建立一次TCP连接
  • 在开发中往往一个页面会向服务器发送多个请求,这个时候如果每次都重新建立连接,就有些不太好了
  • 建立持久化连接的方法就是在请求中带上参数keep-alive
  • HTTP1.1默认就是长连接,但是HTTP1.0中不是,需要手动添加字段开启
  • 建立长连接后,任意一方断开连接都可以

管线化

  • 在实现长连接以前,http请求时一个一个的发的,后一个请求需要等待前面的返回响应才可以发出,会造成阻塞
  • 实现长连接后,可以进行http的并发,也就是管线化

使用Cookie的状态管理

  • 上面说到HTTP是无状态的,那么就会导致一些问题,最常见的就是登录态问题
  • 后来就引入了Cookie,在登录时,向服务端发送请求,服务端会在生成Cookie,然后响应头中添加字段Set-Cookie:'.....',然后客户端会自动向Cookie存储在浏览器,在后续的请求中,自动将Cookie带入到请求头中
//请求 没有Cookie时
Get /reader HTTP/1.1
Host: 服务器

//服务器 生成Cookie,然后添加在响应头中
HTTP/1.1 200 OK
Date: 创建响应时间
Server: Apache
Set-Cookie : pplogid_BFESS=xxxxxxxx; Path=/; Domain=passport.baidu.com; Expires=Tue, 15 Mar 2022 17:11:01 GMT; Max-Age=259200; HttpOnly; Secure; SameSite=None
Content-Type: application/json; charset=utf-8

//请求 有Cookie时
Get /reader HTTP/1.1
Host: 服务器
Cookie: pplogid_BFESS=xxxxxxxx

HTTP报文

  • 报文就是我们所说的请求或响应,以请求举例:请求头就是请求报文首部,请求体就是请求报文主体,请求头与请求体之间使用空行(空白的一行)进行隔开
  • 请求报文首部包含:请求行、请求首部字段、通用首部字段、实体首部字段、其他(如Cookie)
    • 请求行:请求的URI和HTTP版本
  • 响应报文首部包含:状态行、响应首部字段、通用首部字段、实体首部字段、其他
    • 状态行:响应的状态码、原因短语和HTTP版本
  • 首部字段:包含表示请求和响应的各种条件和属性的各类首部

编码提升传输效率

  • HTTP传输时,可以使用原本的数据格式,也可以使用编码格式,使用编码格式会提升传输速率(压缩实体后传输),但是需要消耗计算机一定的CPU
  • 服务器进行压缩,客户端进行解压
  • 常见的编码格式:gzip、compress、deflate、identity(不压缩)

分割发送的分块传输编码

  • 在请求的编码实体资源还没有传输完成之前,浏览器无法显示请求的内容,所以在传输大体积数据时会将数据分割成多块,让浏览器逐步显示页面(分块传输编码)
  • 分块传输编码会将实体主体分成多个部分,用十六进制来标记大小,最后一块使用"0空行"来标记
  • HTTP/1.1中存在一种传输编码机制(Transfer Coding),它可以在通信时按照某种编码方式传输,但只定义作用于分块传输编码

发送多种数据的多部分对象集合

  • 发送邮件时,会用到多种附件,如文本、图片、视频等,这是因为采用了MIME(多用途因特网邮件拓展机制),它允许邮件处理这些类型的数据,它使用一种称为多部分对象集合(Multipart)的方法来容纳多份不同类型的数据
  • 多部分对象集合包含对象:multipart/form-data(文件上传时使用)、multipart/byteranges(状态码206 Partial Content,当返回范围内容时使用)

获取部分内容的范围请求

  • 如果下载文件过程中遇到一些因素导致了下载失败,那么必须重头开始。这时候可以从之前断开处继续下载显然是更好的
  • 要实现这种功能就需要指定下载的范围实体,可以在发送请求的时候进行范围限制(Range Request),具体为在请求头添加Range字段
  • 如果服务器不支持范围请求,会返回状态码200,然后返回所有内容,支持的话就是206和指定部分内容
  • 如果是多重范围的请求Content-Type为multipart-byternages
//5001-10000字节
Range: bytes=5001-10000

//从5001字节到后面全部
Range: bytes=5001-

//多重范围,0-3000字节和5000-7000字节
Range: bytes=0-3000,5000-7000
//如:一份10000字节大小的文件,我们只请求5001-10000字节之内的资源

//请求
GET /test.jpg HTTP/1.1
Host: ......
Range: bytes=5001-10000

//响应
HTTP/1.1 206 Partial Content
Date: 日期
Content-Range : bytes 5001-10000/10000
Content-Length: 5000
Content-type: image/jpeg

http状态码

  • 状态码的作用是告知你们请求的状态,由3位数字和原因短语组成,如200 OK
类型原因短语
1xx请求处理中
2xx请求正常处理完毕
3xx重定向或走缓存,需要进行其他操作
4xx服务器无法处理
5xx服务器处理错误
  • 200 响应成功,拿到响应
  • 204 响应成功,但是不会返回内容,在向服务器发送内容,而客户端不需要对返回内容操作的情况可使用
  • 206 范围请求成功,服务端返回成功
  • 301 永久重定向,如果将网址加入了书签,客户端会自动更新书签
  • 302 临时重定向
  • 303 与302类似,但告诉用户应使用GET方法,哪怕一开始使用的POST请求
    • 301、302、303都会在响应后,浏览器删除本次响应体,然后再次发送GET请求,虽然301、302的标准不允许将POST转为GET但是大家都这么做
  • 304 走缓存,没有响应体
  • 307 临时重定向
  • 400 请求语法错误
  • 403 拒绝请求对应资源
  • 404 服务器没有对应资源
  • 500 服务器内部错误
  • 503 服务器崩溃或或处于异常状态

http首部

  • HTTP首部字段是构成HTTP报文的要素之一,它起到了传递额外信息的作用
  • 结构为键值对形式,一个key可以有多个value,key:value,value

Content-Type: text/html
Keep-Alive: timeout=15,max=100

4种HTTP首部字段类型

  • 通用首部字段
    • 请求报文和响应报文双方都会使用的首部
  • 请求首部字段
    • 从客户端向服务端发送请求报文时使用的首部,补充了请求的附加信息,如:客户端信息
  • 响应首部字段
    • 从服务器端向客户端返回响应报文时使用的首部,补充了响应的附加内容
  • 实体首部字段
    • 针对请求报文和响应报文的实体部分使用的首部,补充了资源内容的更新时间等和实体有关的信息

HTTP/1.1首部字段表

通用首部

首部字段名说明
Cache-Control控制缓存的行为
Connection逐跳首部、连接的管理
Date创建报文的日期时间
Pargma报文指令
Trailer报文末端的首部一览
Transfer-Encoding指定报文主体的传输编码方式
Upgrade升级为其他协议
Via代理服务器的相关信息
Warning错误通知

请求首部字段表

首部字段名说明
Accept用户代理可处理的媒体类型
Accept-Charset优先的字符集
Accept-Encoding优先的内容编码
Accept-Encoding优先的内容编码
Accept-Language优先的语言(自然语言)
AuthorizationWeb认证信息
Expect期待服务器的特定行为
From用户的电子邮箱地址
Host请求资源所在服务器
if-Match比较实体标记(ETag)
if-Modified-Since比较资源的更新时间
if-Modified-Match比较实体标记(与if-Match相反)
if-Range资源未更新时发送实体Byte的范围请求
if-Unmodified-Since比较资源的更新时间(与if-Modified-Since相反)
Max-Forwards最大传输逐跳数
Proxy-Authorization代理服务器要求客户端的认证信息
Range实体的字节范围请求
Referer对请求中URI的原始获取方
TE传输编码的优先级
User-AgentHTTP客户端程序的信息

响应首部字段表

首部字段名说明
Accept-Ranges是否接收字节范围请求
Age推算资源创建经过的时间
Etag资源的匹配信息
Location令客户端重定向至指定URI
Proxy-Autnenticate代理服务器对客户端的认证信息
Retry-After对再次发起请求的时机要求
ServerHTTP服务器的安装信息
Vary代理服务器缓存的管理信息
WWW-Authenticate服务器对客户端的认证信息

实体首部字段表

首部字段名说明
Allow资源可支持的HTTP方法
Control-Encoding实体主体适用的编码格式
Content-Language实体主体的自然语言
Content-Length实体主体的大小(单位:字节)
Content-Location替代对应资源的URI
Content-MD5实体主体的报文摘要
Content-Range实体主体的位置范围
Content-Type实体主体的媒体类型
Expires实体主体过期的日期时间
Last-Modified资源的最后修改日期时间

通用首部

  • 请求双方和响应双方都可以使用的首部

通用首部字段Cache-Control

  • 可以指定Cache-Control的参数(指令)来操作缓存,参数间以,间隔,如下:
  • 要用到的三方:客户端、缓存服务器、源服务器
Cache-Control: private, max-age=0, no-cache
缓存请求指令
指令参数说明
no-cache强制向源服务器再次验证
no-store不缓存请求或响应的任何内容
max-age = [秒]必需响应的最大Age值
max-stale(=[秒])无非必填接收已过期的响应
min-fresh=[秒]必需期望在指定时间内的响应仍有效
no-transform代理不可更改媒体类型
only-if-cached从缓存获取资源
cache-extension-新指令标记(token)
缓存响应指令
指令参数说明
public可向任意方提供响应的缓存
private可省略仅向特定用户返回响应
no-cache可省略缓存前必需先确认其有效性
no-store不缓存请求或响应的任何内容
no-transform代理不可更改媒体类型
must-revalidate可缓存但必需再向源服务器进行确认
proxy-revalidate要求中间缓存服务器对缓存的响应有效性再进行确认
max-age = [秒]必需响应的最大Age值
s-maxage=[秒]必需公共缓存服务器响应的最大Age值
cache-extension-新指令标记(token)

Cache-Control缓存指令详细介绍

private
  • 源服务器告诉缓存服务器,这份缓存只提供给指定的客户端,当其他客户端请求时,不会拿这份缓存
Cache-Control: private

no-cache
  • 如果在请求头上使用:客户端告诉缓存服务器,不要缓存资源,缓存服务器会去源服务器上重新拿资源,源服务器告诉缓存服务器,可以缓存,但使用前需先向它确认(防止文件过期,如果不过期的话使用缓存,过期就拿新文件)
  • 如果在响应头上使用:源服务器告诉缓存服务器,不要缓存这份资源,以后也不需要向他确认
  • 如果响应头的no-cache带有参数,那么参数对应的响应不会被缓存
//不带参数
Cache-Control: no-cache
//带参数
Cache-Control: no-cache=Location

no-store
  • 完全不缓存
max-age
  • 客户端发送的请求包含max-age时,如果缓存在有效期内,那么直接返回缓存信息
  • 当max-age为0,那么缓存服务器会服务器获取数据
  • 当服务器返回的响应中有max-age,缓存服务器将不对资源的有效性进行确认,且将max-age的时间设置为缓存的最长时间
  • HTTP/1.1中,同时存在max-age和Expires,会忽略Expires,HTTP/1.0则相反
s-maxage
  • s-maxage和max-age大致上一致,区别在于,s-maxage只适用于多位用户使用的公共缓存服务器,对于一对一(一个服务器,一个客户端)的场景来说,该属性没有作用
  • 如果同时存在s-maxage和Expires,则忽略Expires
  • 如果同时存在s-maxage和max-age,则忽略max-age
//单位:秒
Cache-Control: s-maxage=604800
min-fresh
  • 告诉缓存服务器一个当前请求之后的时间,如60秒,那么缓存服务器会判断当前缓存60秒后是否会失效,如果失效了,就拿新数据,否则就返回
max-state
  • 如果max-state没有参数,那么无论资源是否过期,都走缓存
  • 如果max-state有参数,只要处于max-state范围内,哪怕过期也走缓存
only-if-cached
  • 如果缓存服务器有就返回,如果没有就返回504
  • 它不要求缓存服务器验证资源有效性也不会重新向源服务器发送请求
must-revalidate
  • 缓存服务器会向源服务器验证资源有效期,如果失效且无法获取新资源,那么返回504
  • 使用must-revalidate会忽略max-stale
proxy-revalidate
  • 要求缓存服务器验证资源有效期
no-transform
  • 要求缓存不改变实体主体的媒体类型
  • 可以用作防止缓存或代理压缩图片等操作

Cache-Control扩展

cache-extension(token)
  • 通过cache-extension标记(token),可以扩展Cache-Control首部字段指令
  • Cache-Control是没有community指令的,这里进行拓展(=后面的可以是token,也可以是其他内容)
  • 如果缓存服务器不能理解community指令,就会忽略这个指令,但不会影响其他指令
//官方文档格式:token [ "=" ( token | quoted-string ) ]
//把community带入到token,也就是属性名,"UCI"带入到( token | quoted-string )这样理解
Cache-Control: private, community="UCI"

Connection

  • 控制不再转发给代理的首部字段(在转发给源服务器的时候会删除Connection值对应的首部字段)
  • 管理持久连接
控制不再转发给代理的首部字段
//客户端->代理服务器
GET /index.html HTTP/1.1
Upgrade: HTTP/1.1
Connection: Upgrade

//代理服务器->源服务器 (删掉了Connection字段和Connection指定删除的Upgrade字段)
GET /index.html HTTP/1.1

管理持久连接
  • 上面有说到,HTTP/1.0默认是不开启持久连接的,那么开启的话就要用到Keep-Alive和Connection:Keep-Alive
  • 有开启就有关闭,关闭的时候将Connection的属性设置为close即可
//客户端
GET / HTTP/1.1
Connection: Keep-Alive

//服务端
HTTP/1.1 200 OK
Keep-Alive:timeout=10, max=500
Connection:Keep-Alive

//关闭长连接
Connection:close

Date

  • 表示创建HTTP报文的日期时间
//HTTP/1.1使用RFC1123中的日期格式
Date: Tue,03 Jul 2012 04:40:59 GMT
//之前的HTTP协议使用RFC850中的日期格式
Date: Tue, 03-Jul-12 04:40:59 GMT
//还有一种格式,与C标准库内的asctime函数输出一致
Date: TUE Jul 03 04:40:59 2012

Pragma

  • HTTP/1.1之前版本的遗留字段,因为向后兼容,所以保留了下来
  • 属于通用头部字段,只用于客户端请求使用,属性值为no-cache,要求中间服务器不使用缓存
  • 如果所有中间服务器都以HTTP/1.1位基准,那么就可以使用Cache-Control:no-cache来达到相同效果,但不能保证的情况下,还是两个一起使用比较好
Cache-Control:no-cache
Pragma: no-cache

Trailer

  • 提醒服务器关注哪个字段
  • 常在分块传输的时候使用
//让服务器关注Expires字段,因为当分块长度为0,代表分块传输结束,这时候就出现首部字段Expires了
HTTP/1.1 200 OK
Date:.......
Content-Type:.....
Transfer-Encoding: chunked
Trailer: Expires

....报文主体

0 //表示分块最后一块
Expires: 过期时间

Transfer-Encoding

  • 规定传输报文主体采用的编码格式
  • HTTP/1.1的传输编码格式只针对分块传输编码生效
HTTP/1.1 200 OK
Date:创建报文日期时间
Cache-Control:public, max-age=604800
Content-Type:text/javascript;charset=utf-8
Expires:过期时间
X-Frame-Options:DENY
X-XSS-Protection:1;mode=block
Content-Encoding:gzip
Transfer-Encoding:chunked
Connection:keep-alive

cf0 //16进制,10进制为3312
...3312个字节的分块数据...

392 //16进制,10进制为914
...914个字节的分块数据....

0//分块结束啦

Upgrade

  • 询问对方是否可以使用更高的版本(或指定版本)进行通信
  • 使用Upgrade的时候,需要在Connection的属性添加Upgrade
  • Upgrade仅作用于相邻的两个机器(客户端到接收请求的第一台机子)
  • 对应有Upgrade的请求,服务器可返回状态码 101 Switching Protocols
//客户端
GET /index HTTP/1.1
Upgrade:TLS/1.0
Connection: Upgrade
//服务器
HTTP/1.1 101 Switching Protocols
Upgrade:TLS/1.0,HTTP/1.1
Connection:Upgrade

Via

  • 追踪客户端与服务器之间的请求和响应报文的传输路径
  • 报文每经过代理或网关,都会在首部字段Via中添加该服务器的信息
  • 也可以用来避免请求回环
  • 如果只是单纯的追踪路径,可配合TRACE请求使用,如果请求为TRACE,且Max-Forwards:0,那么代理服务器不会再进行转发,而是直接返回响应,当然,会带着Via
//客户端->第一台代理服务器
GET / HTTP/1.1
//第一台代理服务器->第二台代理服务器
GET / HTTP/1.1
Via: 1.1 gw.hackr.jp(Squid/3.1)
//第二台代理服务器->源服务器
GET / HTTP/1.1
Via: 1.1 gw.hackr.jp(Squid/3.1)
1.1 a1.example.com(Squid/2.7)
//Via的字段上的1.1指的是接收服务器上应用的HTTP版本

Warning

  • 从HTTP/1.0的Retry-After演变过来的字段,是HTTP/1.1开始新增的字段
  • 作用是告知用户一些缓存相关的问题警告
  • HTTP/1.1有7种警告码
警告码警告内容说明
110Response is state(响应已过期)代理返回已过期的资源
111Revalidation failed (再验证失败)代理再验证资源有效性时失败(服务器无法到达等原因)
112Disconnection operation(断开连接操作)代理与物联网连接被故意切断
113Heuristic expiration(试探性过期)响应的使用期超过24小时了(有效缓存的设定时间大于24小时的情况下)
199Miscellaneous waening(杂项警告)任意的警告内容
214Transformation applied(使用了转换)代理对内容编码或媒体等类型进行了某些处理
299Miscellaneous persistent warning(持久杂项警告)任意的警告内容
//格式
Warning: [警告码][警告的主机:端口号] "警告内容" ([日期时间])
//例子
Warning: 113 xxx.xxx.com:8080 "Heuristic expiration" Tue, 03 Jul 2012 05:09:44 GMT

请求首部字段

Accept

  • 通知服务器,用户代理能处理的媒体类型
  • 可以使用q来设置优先级,q的值为0~1.0,可为小数,如果不设置,默认为1.0,同等权重,采用从前到后的顺序
  • 值采用type/subtype格式
  • 文本文件:text/html、text/plain、text/css、application/xhtml+xml、application/xml
  • 图片文件:image/jpeg、image/gif、image/png
  • 视频文件:video/mpeg、video/quickime
  • 应用程序使用的二进制文件:application/octet-stream、application/zip
//如过可以发送text/html格式,就发送text/html,如果不行的话发送text/plain格式
//text/plain; q=0.3为设置text/plain权重为0.3,而不是设置text/html权重为0.3
Accept:text/plain; q=0.3,text/html

Accept-Charset

  • 可用来通知服务器用户代理支持的字符集 字符集的相对优先顺序(与Accept一样,使用q来设置优先级)
  • 主要作用于内容协商
Accept-Charset: iso-8859-5,unicode-1-1;q=0.8

Accept-Encoding

  • 告知服务器用户代理支持的内容编码和内容编码的优先级顺序
  • gzip、compress、deflate、identity(不压缩或不会变化的默认编码格式)
Accept-Encoding:gzip,deflate

Accept-Language

  • 告知服务器,用户代理能处理的自然语言集(中文或英文),也可设置优先级(q,同Accept一样)
Accept-Language:zh-cn,zh;q=0.7,en-us,en;q=0.3

Authorization

  • 告知服务器,用户代理的认证信息(证书值),在服务器返回401后,再次携带Authorization字段向服务器发送请求
//客户端
GET /index
//服务器告知客户端需要认证信息
401 Unauthorized
WWW-Authenticate:.....
//客户端再次发送请求,且带上Authorization字段
GET /index
Authorization:........

Expect

  • 客户端告知服务器期望出现的某种特定行为,如果服务器无法理解,那么返回417

From

  • 告知服务器用户代理的邮箱地址,可以在出现某些问题后,通过人为的通过邮箱进行联系
  • 也有人不使用From,而使用User-Agent来实现相同功能
From: xxxxxx.jp

Host

  • 告知服务器希望建立连接的目标,可为ip和域名(可以添加端口号)
  • 值可为空

If-Match

  • 客户端告知服务器进行条件判断
  • 服务器根据If-Match的值与ETag的值进行判断,如果等就返回,否则返回412
  • If-Match的值可为*,当为*的时候代表通配符,这时候比较全部为true,只要资源存在就返回

If-Modified-Since

  • 告知服务器一个日期时间,如果请求资源在这个日期时间后更新过,那么返回资源,如果没有更新过返回304
  • 可以根据Last-Modified来确定最后更新时间
//客户端请求index.html,且资源要在2004年4月15日之后更新过
GET /index.html
If-Modified-Since:Thu, 15 Apr 2004 00:00:00 GMT
//如果更新过,返回
200 OK
Last-Modified: Sun,29 aUG 2004 14:03:01 GMT
//如果没更新过
304 Not Modified

If-None-Match

  • 只有在If-None-Match的值不等于ETag的值得时候才会处理该请求,与If-Match作用相反
  • 值可以为*
  • 可以在GET和HEAD中使用If-None-Match,防止走缓存

If-Range

  • 服务器将If-Range值与ETag值进行比对,相同的话,返回Range指定的范围,否则返回全部内容
  • 如果使用If-Match的话,当匹配失败,服务器会返回412,然后客户端会自动再次发送请求,这次服务器会返回全部内容
//使用If-Range
GET /index.html
If-Range:"121212"
Range: bytes=5001-10000

//服务器比对index.html的ETag,相等,返回206 和 指定范围内容
206 Partial Content
Content-Range:bytes 5001-10000/10000
Content-Length:5000
//若不一致,返回200和全部内容,一级ETag
200 OK
ETag:"9999"

//使用If-Match
GET /index.html
If-Match:"121212"
Range: bytes=5001-10000

//匹配成功,返回和If-Range一致,不写了
//匹配失败,返回412
412 Precondition Failed

//客户端自动再次发送请求
GET /index.html

//服务端返回
200 OK
ETag:"9999"

//区别在于如果使用If-Match,且匹配失败,那么会发送两次请求

If-Unmodified-Since

  • 当服务器资源在指定时间后未更新,那么返回资源,否则返回412
  • 与If-Modified-Since相反

Max-Forwards

  • 使用TRACE或OPTIONS方法的时候,可配合Max-Forwards查找问题
  • 使用Max-Forwards设置一个十进制的值,每经过一层中转,该值就-1,当值为0的时候,返回
  • 当有多台服务器进行中转,而不确定哪台出现问题导致没有响应的时候,可以使用这个字段进行测试

Proxy-Authorization

  • 接收到代理服务器发送过来的认证资质询问时,客户端会使用Proxy-Authorization发送认证信息
  • 如果是客户端和服务器,那么也可以使用Authoriztion,效果一致

Range

  • 范围请求设置范围,上面有说过,不说啦

Referer

  • 服务器可根据Referer得知当前请求时从那个页面发起的
  • 注意:当在https页面中,发起http请求,那么请求的Referer带不过来。
  • 解释:如果来源页来自于安全协议https,那么在非安全http请求时,客户端不应包含referer头部字段。
Referer: http://xxx.xxx.com/index.html

TE

  • 告知服务器,客户端能够处理响应的传输编码方式和优先级(q)
  • 和Accept-Encoding相似,但是用于传输编码
  • 也可指定分块传输的编码格式,将他trailers放在TE的值中即可,那么TE会识别Trailer关注的值
//告知传输编码格式
TE:gzip,deflate;q=0.5

//告知分块传输编码格式
TE:trailers

User-Agent

  • 会将创建请求的浏览器的信息添加进去,然后传递给服务器
  • 如果中间经过代理,那么也有可能会在上面添加上代理服务器的信息
User-Agent:Mozilla/5.0............

响应首部字段

Accept-Ranges

  • 告知客户端,服务器是否可以处理范围请求
  • 如果可以处理,值为范围请求的bytes,否则为none

Age

  • 如果是源服务器,那么Age代表的是源服务器什么时候创建的响应,单位为秒
  • 如果创建响应的是缓存服务器,那么代表的是缓存后的响应再次发起认证到认证完成的事件值
  • 代理创建响应,必须要添加Age
Age:600

ETag

  • 服务器为资源创建的唯一标识,字符串类型
  • ETag可分为强Etag和弱ETag
    • 强ETag:只要资源发生变化,那么生成一个新的ETag
    • 弱ETag:当资源发生细微变化时不改变,当发生大变化才生成新的ETag,且在字段前增加W/
    • 弱ETag只用于提示资源是否相同
ETag:"1212"

ETag:W/"1212"

Location

  • 配合3xx状态码实现重定向
  • 值为一个URI,几乎所有的浏览器识别到Location时,都会自动跳转到它的值对应的URI上

Proxy-Authenticate

  • 把代理服务器要求的认证信息发给客户端

Retry-After

  • 告知客户端在多久后再次发送请求
  • 主要配合5xx和3xx状态码使用
  • 值可以使具体的日期时间,也可以是创建响应后的秒数

Server

  • 告知客户端当前服务器上安装的HTTP服务器应用程序信息
Server: Apacbe/2.2.17 (Unix)

Vary

  • 告知缓存服务器指定缓存匹配的字段,如果相同(请求上的字段和资源的字段对应),则返回,否则向源服务器重新获取
//客户端
GET /index
Accept-Language:en-us
//缓存服务器,相同直接返回
GET /index
Accept-Language:en-us
//源服务器 //匹配Accept-Language字段的才走缓存
Vary: Accept-Language

WWW-Authenticate

  • 告知客户端适用于访问URI所指定资源的认证方案

实体首部字段

  • 作用于报文,可以补充内容的信息

Allow

  • 告知对方可以使用的请求方法
  • 当服务器接收到不支持的HTTP方法时,会返回405和Allow
Allow:GET, HEAD

Content-Encoding

  • 告知客户端服务器对实体的主体部分选用的内容编码格式
  • 内容编码指的是在不丢失实体信息的前提下进行的压缩

Content-Language

  • 资源的自然语言类型
//该资源是中文
Content-Language:zh-CN

Content-Length

  • 实体主体的大小,单位为字节

Content-Location

  • 给出报文主体部分对应的URI
  • 和Location不同,它表示的是报文主体返回资源对应的URI,而不是重定向那些

Content-MD5

  • 加密处理,值是一个经过MD5算法处理过后,再进行base64处理的的值,服务器会使用相同的编码规则,对内容进行处理,然后比对,判断资源的有效性
  • 因为MD5处理过后是128位的二进制,但首部无法使用二进制,所以又使用了base64编码二次处理

Content-Range

  • 范围请求的范围和文件整个大小

Content-Type

  • 内容类型

Expires

  • 将资源失效的日期告知客户端,缓存服务器在接收到含有此字段的响应后,会以缓存来应答请求,如果超出指定时间,那么重新向源服务器获取资源,否则返回缓存
  • 如果Cache-Control中有max-age,那么会优先处理max-age

Last-Modified

  • 资源最终修改日期时间

为Cookie服务的首部字段

setCookie

  • 响应首部字段
  • 浏览器接收到后,会自动将内容存储在客户端 | 属性 | 说明 | | ---- | ---- | | name=VALUE | 赋予Cookie的名称和值,必填 | | expires | Cookie的有效期(如果为空,浏览器关闭就会清除expires) | | path=PATH | 将服务器上的文件目录作为Cookie的适用对象(若不指定,默认为文档所在的文件目录) | | domain=域名 | Cookie适用对象的域名(若不指定,默认为创建Cookie的服务器的域名) | | secure | 仅在HTTPS时才会发送Cookie | | HttpOnly | 加以限制,使Cookie不能被JavaScript脚本访问,如document.cookie拿不到这个值 |
setCookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path=/; domain=.baidu.com

//限制在HTTPS下
setCookie: name=value;secure

Cookie

  • 请求首部字段
  • 请求的时候将本地匹配的Cookie自动带上

其他首部字段

  • HTTP首部字段可以自行拓展,所以会有一些非标准化的首部字段,下面列举一些常见的

X-Frame-Options

  • 属于HTTP响应首部,用来控制网站内容在其他Web网站的Frame标签内的显示问题,防止点击劫持攻击,目前所有浏览器都支持了
    • DENY 表示拒绝,不允许嵌套在Frame中
    • SAMEORIGIN 仅同源域名下得页面匹配时可以加载
X-Frame-Options:DENY

X-XSS-Protection

  • 属于HTTP响应首部,是针对跨站脚本攻击XSS的一种对策
    • 0 将XSS过滤设置成无效状态
    • 1 将XSS过滤设置成有效状态
X-XSS-Protection:1

DNT

  • 属于HTTP请求首部,表示拒绝个人信息被收集,可以用来拒绝被精准广告追踪
  • 值:
    • 0 同意被追踪
    • 1 拒绝被追踪

HTTPS

HTTP的缺点

  • 通信使用明文(不加密),内容可能会被窃听:
    • HTTP本身不具备加密的功能,所以也不会对报文整体进行加密,当然,我们可以人为的使用MD5等对字段进行加密,但这不属于HTTP本身
  • 不验证通信方的身份,因此可能遭遇伪装
  • 无法证明报文的完整性,所以报文有可能已经被篡改

加密方式

通信的加密

  • HTTP协议中没有加密机制,但可以通过和SSL(安全套接层)或TLS(安全传输层协议)的组合使用加密HTTP的通信内容
  • 与SSL组合的HTTP称为HTTPS(HTTP Secure 超文本传输安全协议)

不验证通信方的身份就可能遭遇伪装

任何人都可发起请求
  • 在HTTP中,只要后端没有限制,那么就不存在确认通信方的处理步骤,可以理解为,任何人都可以发送请求,服务器只要接收到请求,不管对方是谁都会返回一个响应,那么就会有一些隐患:
    • 无法确定请求发送至目标的Web服务器是否是按照真实意图返回响应的那台服务器。有可能是已伪装的Web服务器(拦截请求)
    • 无法确定响应返回到的客户端是否是按照真实的意图接收响应的那个客户端。有可能是伪装的客户端(拦截响应)
    • 无法确定正在通信的对方是否具备访问权限,因为某些Web服务器上保存着重要的信息,只想发给特定的人
    • 无法判断请求来自何方,出自谁手
    • 即使是无意义的请求也会照单全收,无法阻止海量请求下得DoS攻击(拒绝服务攻击)
查明对手的证书
  • SSL不仅仅提供加密处理,还使用了一种被称为证书的手段,可以用来确定对方的身份
  • 证书由值得信任的第三方机构颁发,具备一定的权威性,而且伪造证书从技术角度来说也是很困难的,这样会将一些非法之徒拒之门外
  • 使用证书证明通信方身份也减少了客户个人信息泄漏的危险性
  • 谷歌浏览器地址栏的左上角可以进行查看(有cookie和证书信息),如果是http就会显示不安全,https就会有对应的证书信息,可以点击进行查看

无法证明报文的完整性,可能内容已篡改

  • 所谓的完整性就是指信息的准确性,如果已经被拦截修改,那显然不具备完整性了,因为信息代表的内容已非用户本意,但是接收方又察觉不到,像这种在中途篡改信息的手段称之为MITM(中间人攻击)
  • 因为HTTP无法确定发出的文件和接收的文件是一致的,所以会导致这种问题
如何防止篡改
  • 有一些手段可以在一定程度上实现和保证发出的文件和接收的文件是一致的,如MD5生成的散列值和数字签名,但这些其实也是可以被改动的,只能拦截一部分技术不太好的
  • 那有一种更好的方法,那就是HTTPS,因为SSL提供认证和加密处理以及摘要功能。

HTTP+加密+认证+完整性保护=HTTPS

  • HTTPS并不是一种全新的协议,而是HTTP通信的部分接口使用SSL和TLS协议代替了而已
  • 通常HTTP直接和TCP通信,使用SSL时,则变成了先和SSL通信,再由SSL和TCP通信,相当于HTTP找了一个保安
  • SSL独立于HTTP,所以不止是HTTP,其他应用层协议也可以配合SSL协议使用,因为SSL可以说是目前最好用的网络安全技术了
  • HTTPS在HTTP的基础上,增加了SSL的加密、证书和完整性保护等功能

相互交换密钥的公开密钥加密技术

  • SSL采用的是一种叫做公开密钥加密(Public-key cryptography)的加密处理方式
  • 近代的加密方式中加密算法是公开的,但是加密与解密需要用到密钥,所以我们需要保证密钥的安全,如果密钥泄漏,那么也就没有安全一说了,因为任何人都可以使用密钥进行解密
共享密钥加密
  • 加密和解密共用一个密钥的方式称为共享密钥加密,也可以称为对称密钥加密
  • 这种方式需要在发送请求的时候,将密钥带给接收方(如果不带,对方就无法对资源进行解密),这样就有可能被人从中间捕获(上面说的中间人攻击),那样就失去了加密的意义
  • 缺点:不是特别的安全
  • 优点:快
公开密钥加密
  • 公开密钥加密的方式很好的解决了共享密钥加密的问题
  • 公开密钥采用两把非对称的密钥,可以为私有密钥,一个为公开密钥
    • 私有密钥不公开,用来解密
    • 公开密钥可以随意发布,用来加密
    • 两者之间的关系就是锁和钥匙的关系
  • 流程:请求方获取到接收方的公开密钥,然后使用公开密钥进行加密,再进行传输,接收方接收到后,使用私有密钥进行解密
  • 好处:不用向共享密钥那样在请求时将密钥带给对方,也就没有了上述问题
  • 问题:既然我们可以获取到他的公开密钥,用来加密,那么为什么不能利用这个反推进行解密呢?
    • 解密过程是对离散对数进行求值,这样极其困难的。如果对一个非常大的整数快速进行因式分解,那样的确存在解密的可能。但是目前技术还没达到这种水平。
  • 缺点:相对共享密钥来说,比较慢
HTTPS采用两种加密方式的结合
  • 上面有介绍两种方式的优缺点,那么HTTPS就是结合了他们的优缺点进行了混合使用,也就是混合加密机制
  • 在初次交换密钥环节,使用慢但是安全的公开密钥,将后续使用的共享密钥传递过来
  • 然后,在后续的传输中使用相对快速的共享密钥加密(上面将共享密钥已经传过来了,这个时候就不需要再传了,也就减少了安全问题,只在传输的时候加密即可)
证明公开密钥真实性的证书
  • 我们在使用公开密钥加密方式的时候,需要先获取接收方的公开密钥,那这个时候如果在传输公开密钥的过程中被攻击者替换掉,那么我们也不知道
  • 解决方法:使用数字证书认证机构(CA, Certificate Authority)和其他机关办法的公开密钥证书
  • 数字证书机构是客户端与服务器双方都可以信赖的第三方。可以理解为担保人或公证处
  • 它的业务流程:
    • 服务器向机构提出公开密钥的申请
    • 机构审核后,对申请的公开密钥做数字签名,然后将已签名的公开密钥绑定在公钥证书
  • 使用证书的流程
    • 服务端有了证书后,会将这个公钥证书发给客户端,然后进行公钥加密方式通信
    • 公钥证书可以称为证书也可以称为数字证书,很多文档内称为它CA证书
    • 接收到证书的客户端可以使用机构的公开密钥,对证书上的数字签名进行验证,一旦通过,那么客户端就可以得知这个公开密钥时真实可信赖的了
  • 细心的可能会发现这些步骤还是存在个问题,那就是无论是认证的时候,或者是客户端验证证书有效性的时候,也用到了认证机构的公开密钥,那这个是如何保证真实有效性的?
    • 浏览器厂商为了解决这个问题,通常会在浏览器中直接植入这些常用认证机构的公开密钥
  • 证书需要向认证机构(CA)购买,价格以实际情况为准,通常一年需要600左右
可证明阻止真实性的EV SSL证书
  • 证书的一个作用就是上面说的,来校验公开密钥。
  • 但是它还有其他作用,比如说证明这台服务器背后的企业是否真实存在,拥有这种特性的证书就是EV SSL证书
  • EV SSL证书是基于国际标准的认证指导方针颁发的证书,也得到了高度认可,所以认证很严格。
  • 有这个证书的网站URI输入框左侧不会是红色的警告标志各个浏览器不一样
  • 我们日常都不太在意这个URI左侧,所以也不会留意这个东西,其实它可以防止用户被钓鱼攻击,发现红色警告就不要相信网站安全啦,警示作用
自认证证书
  • 如果使用OpenSSl这套开元程序,每个人都可以构建属于自己的认证机构,然后自己给自己发证书
  • 但是因为没有信誉背书,这个东西是不被承认的,这类证书称为自认证证书
  • 在使用这类证书的时候,浏览器会给出提示,如:无法确认链接安全性该网站的安全证书存在问题

HTTPS的请求流程

  1. 客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL版本、加密组件(Cipher Suite)列表(所使用的加密算法和密钥长度等)
  2. 服务器可进行SSL通信时,返回Server Hello报文,和客户端一样,在报文中包含SSL版本和加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的
  3. 之后服务器发送Certificate报文报文中包含公开密钥证书
  4. 最后服务器发送Server Hello Done 报文通知客户端,最初阶段的SSL握手协商部分结束
  5. SSL第一次握手结束后,客户端以Client Key Exchange报文作为回应,报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密
  6. 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密
  7. 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准
  8. 服务器同样发送Change Cipher Spec报文
  9. 服务器同样发送Finished报文
  10. 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到SSL的保护。
  11. 应用层协议通信,发送HTTP请求
  12. 最后由客户端断开连接。断开连接时,发送close_notify报文。然后再发送TCP FIN来关闭TCP通道(四次挥手)
  • 在上述流程中,应用层发布数据的时候会附加一种叫做MAC(Message Authentication Code)的报文摘要。这个Mac可不是最前面的那些Mac地址。,Mac能够查知报文是否遭到篡改,从而保护报文的完整性

SSL和TLS

  • HTTPS使用SSL和TLS这两个协议
  • SSL技术最初由网景公司开发,且一直到SSL3.0都是由网景开发的,目前的主导权转移到IETF(Internet Enguneering Task Force, Internet工程任务组)的手中
  • IETF以SSL3.0位基准,后续又指定了TLS1.0、TLS1.1、和TLS1.2
  • TLS是以SSL为原型开发的协议,通常我们被问到HTTPS的时候会将他和SSL混为一谈,都说是HTTP+SSL。目前主流的版本是SSL3.0和TLS1.0
SSL速度问题
  • HTTPS使用了SSL,从上面的12个步骤中也可以看到,在安全性大大提高的同时,它也牺牲了一部分的时间,所以说处理速度会变慢
    • 原因1:通信过程慢
    • 原因2:解密和加密需要消耗大量的CPU和内存资源,处理速度慢
  • 解决方法:使用SSL加速器(专用服务器,一种硬件设备)来专门改善该问题,它可以提高SSL的计算速度,可以分担负载

基于http的功能追加协议

HTTP的瓶颈

  • 在早期,我们直接通过页面加载时的一个HTTP请求拿到页面。但是这样可能会有一定的问题,比如我拿页面的时候,服务器上的一些数据不是最新的,那么导致我浏览的也就不是最新的。或者说这个页面的内容特别多,一次性返回,会导致很长的白屏时间等等。
  • 为了解决这种问题,ajax就出现了,他的全称为(Asynchronous Javascript and XML 异步JavaScript与XML技术),它使用的是XMLHttpRequest这个api
    • 我们可以在首屏中使用http请求拿到基础的一个页面,然后通过js中使用ajax来请求所需要的信息,配合Dom方法来将信息渲染到页面中,也就是常说的局部刷新功能
    • 但是前面也说了http和https的优缺点,我们会发现如果频繁的请求,那么会有大量的时间浪费在建立连接和断开连接上,这点时间虽然不多,但是能否有更优的方案呢

Coment

  • 一种服务端推送技术,在接收到请求后,延迟响应,等待请求对应的数据更新后,向客户端进行响应,因为这一特点,所以服务器需要保留响应,而且这次连接的时间也明显增长了
  • 优点:可以保证信息的最新
  • 缺点:连接时长增加

SPDY协议

  • SPDY没有完全改写HTTP协议,在TCP/IP的应用层和传输层之间通过新加会话层的形式运作。同时,为了安全性,SPDY在通信中使用了SSL。
  • 它以会话层的形式加入,控制数据的流动,但是还是使用HTTP建立连接
  • 好处:
    • 多路复用流:通过一次TCP连接,可以多次处理HTTP请求,减少连接次数
    • 赋予请求优先级:它不仅仅可以无限制的实现并发请求,还可以给这些请求分配优先级,这个优先级是为了在发送多个请求的时候,解决因带宽低而导致的响应边慢问题
    • 压缩HTTP首部:压缩HTTP的请求和响应的首部,那么体积就小了,体积小,也就会更快
    • 推送功能:支持服务器主动向客户端推送数据,不需要等待客户端请求
    • 服务器提示功能:服务器可以主动提示客户端请求所需要的资源(让客户端走缓存,避免多余请求)
  • 结构:HTTP(应用层)、SPDY(会话层)、SSL(表示层)、TCP(传输层)

HTTP2

+浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(PC浏览器大约6-8个,移动端大约4-6个)。超过限制数目的请求会被阻塞。

  • 解决方法:资源不放在一个域名下
  • HTTP2采用二进制流,可以采用多路复用的形式,来解决上述问题
  • HTTP2的头部比HTTP1.1小,所以更快
  • www.zhihu.com/question/34…
HTTP个版本区别
  • 0.9版本,只是单行协议,只有GET,只能简单获取资源
  • 1.0版本:
    • 增加了头、缓存等信息,可以进行复杂的交互,但对于一些请求比较多的情况不太友好,因为HTTP1.0中请求时串行的,如果有一个请求没有回来,就会阻塞,也就是队头阻塞
    • 实际上影响性能的一大原因是连接,因为需要重复进行TCP所以会造成时间的浪费,可以设置Connection:Keep-Alive,来进行长连接
  • 1.1版本:
    • 1.1版本默认就是长连接,可通过Connection:Close关闭长连接
  • 2.0版本:
    • 采用二进制流传输,传输单位为帧
    • 增加多路复用,实现并发(与SPDY协议类似,因为这部分就是借鉴的SPDY协议)
    • 对header进行压缩,采用HPACK算法,客服端与服务端维护两个表(使用的是字典数据结构),最后使用Huffman算法压缩

WebSocket

  • 出现原因:WebSocket由W3C制定标注,解决了Ajax和Coment里XMLHttpRequest附带的缺陷
  • 主要功能:
    • 推送功能:支持由服务器向客户端主动推送,不必等待客户端请求
    • 减少通信量:只要建立起WebSocket连接,就希望一直保持再连接状态,而且WebSocket的首部信息比较小
  • 为了实现WebSocket通信,在HTTP连接建立之后,需要完成一次握手(Handshaking)
握手·请求
  • 为了实现WebSocket通信,需要用到HTTP的Upgrade首部字段,告知服务器通信协议改变,用来达到握手目的
  • Sec-WebSocket-Key字段内记录着握手过程中不必不可少的键值。Sec-WebSocket-Protocol字段内记录着使用的子协议
    • 子协议按Websocket协议标准在连接分开使用时,定义那些连接的名称。
GET /... HTTP/1.1
Host: ...
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: ........
Origin: .......
Sec-WebSocket-Protocol: chat,superchat
Sec-WebSocket-Version: 13
握手·响应
  • 对于之前的请求,返回状态码101 Switching Protocols的响应
  • Sec-WebSocket-Accept的字段值是由握手请求中的Sec-WebSocket-Key的字段值生成的
  • 成功握手确立WebSocket连接后,通信时不再使用HTTP的数据帧,而采用WebSocket独立的数据帧
总结
  • WebSocket建立连接的时候需要基于HTTP请求,在请求的时候带上Upgrade:websocket,然后服务器返回101,这个时候还是HTTP协议
  • 客户端接收到信息后,就变成Websocket协议了
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: ..............
Sec-WebSocket-Protocol:chat

Web攻击

XSS

  • 跨站脚本攻击(Cross-Site Scripting, XSS)
  • 是指通过存在漏洞的Web页面提交信息,在提交的时候输入一些html标签等,当数据回填的时候,浏览器将这些字符串识别为html,然后执行。
  • 防范手段:将一些特殊字符进行转义
/*
    提交表单后,一般都会有一个修改的功能
    在输入的时候我们将<script>console.log(1)</script>作为内容提交
    当返回的时候,浏览器检测到<script>console.log(1)</script>会自动渲染成script标签
    如果这个script不是log,而是获取拿到提交按钮的dom,然后绑定点击事件,在点击后将账号和密码同时发送给恶意的人呢
    又或者,拿到cookie,然后发送给攻击者等
*/

SQL注入

/*
    以查询举例,通常我们查询都是将要查询的字段给到服务端
    然后服务端调用SQL语句查询:如下
        select * 代表所有字段
        from 表明代表从那个表中查询
        where 后跟的是查询条件
        and 后就是和js中的&&一样
    现在:假设flag为1的是我想给用户看到的,flag为0的代表我不想让用户看到的
*/
    //符合我预期的SQL
    select * from 表名 where name='cc' and flag=1;
    //恶意的SQL ,name的值是前端传过来的,如果传'cc'--'那么依然会查询cc,然后--后会注释
    select * from 表名 where name='cc'--' and flag=1;
    //为什么说是恶意,因为在SQL中and后的flag为为筛选条件之一,但是SQL中--后的内容会被认为注释不生效,所以用户就可以拿到全部的信息,这个是不符合我们预期的

跨站点请求伪装

  • 跨站点请求伪造攻击(Cross-Site Request Forgeries,CSRF),是指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等状态更新,属于被动攻击。
  • 危害:
    • 利用已通过认证的用户权限更新设定信息等
    • 利用已通过认证的用户权限购买商品
    • 利用已通过认证的用户权限在留言板上发表言论
//背景:一个留言板页面,需要用户认证才可登录

用户A在留言板留下一个恶意链接(作用是让别人发布不良言论,但是需要用户登录)
用户B点击这个链接,进入A的陷阱,这个时候就会触发A的逻辑,以B的身份在留言板发布不良言论,但B是没有感知的,他只是认为自己访问了一个链接

//上述内容需要用户已登录,但背景中已说明,进入留言板需要登录,所以满足条件