基础概念:
URL:
uri包含url和urn。目前web只有url比较流行。
- URI: 统一资源标识符
- URL:统一资源定位符
- URN:统一资源名称
请求和相应报文:
请求报文:
响应报文:
HTTP方法:
客户端发送的请求报文 第一行 为请求行,包含了方法字段。
get:获取资源
当前网络中绝大部分请求是get方法。
head: 获取报文首部
和get方法一样,但是不返回报文实体的主体部分。
主要用于确认URL的有效性以及资源更新的日期时间等。
post: 传输实体的主体
post请求主要用来传输数据,而get请求主要用来获取资源。 下文有
具体比较。
put:上传文件
由于自身不带验证机制,任何人都可以上传文件,存在安全性问题,一般不使用该方法。
patch:对资源进行部分修改:
put也可以用于修改资源,但是只能完全替代原始资源,patch允许部分修改。
delete :删除文件:
与put功能相反,并且不带验证机制,任何人都能删。
DELETE /file.html HTTP/1.1
options :支持查询的方法
查询指定的url能够支持的方法。会返回Allow:GET,POST.,OPTIONS 等这样的内容。
connect:要求在与代理服务器通信时建立隧道
使用SSL和TLS协议把通信内容加密后经网络隧道传输。
CONNECT WWW.CSDN.COM:433 HTTP/1.1
TRACE :追踪路径
服务器会将通信路径返回给客户端。
发送请求时,在MAX-Forwords首部字段中填入数值,每经过一个服务器就会减1,当数值为0时就会停止传输。
通常不会使用TRACE,并且其容易受到XST攻击(跨站追踪)
HTTP状态码:
服务器返回的响应报文的第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。
1xx开头 : 信息
- 100 Continue: 表明到目前为止都很正常。
2xx开头 : 成功
- 200 OK
- 204 No content: 请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端给服务端发送消息,而不需要返回数据时使用。
3xx开头:重定向
- 301 :永久性重定向
- 302 :临时重定向
- 303 : 临时性重定向,但是明确要求客户端应该采用get方法获取资源。
4xx开头:客户端错误
- 400 :请求报文中存在语法错误
- 401 :该状态码表示发送的请求需要认证信息(BASIC认证,DIGEST认证)。 如果之前进行过一次认证,则表示用户认证失败。
- 403 :请求被拒绝
- 404 :没有发现url对应的ip
5xx 服务器错误:
- 500 : 服务器正在执行请求时发生错误。
- 503: 服务器暂时处理超负荷或者停机维护状态,无法处理请求。
HTTP首部:
有四种类型的首部字段:通用首部字段,请求首部字段,响应首部字段,实体首部字段。
通用首部字段
请求首部字段
响应首部字段:
实体首部字段
具体应用
Cookie
HTTP协议是无状态的,主要是为了让HTTP协议尽可能简单,使得它能够处理大量事务。http/1.1引入了cookie来保存状态信息。
Cookie是服务器发送到用户浏览器并保存到本地的一小块数据,它会在浏览器之后向同一服务器发起请求时被携带上,用于告知服务端两个请求是否来自于同一个服务器。由于每次都需要携带cookie数据,因此会带来额外的性能开销,尤其在移动环境下。
cookie曾一度用于客户端数据的存储,因为当时并没有其它合适的存储办法而作为唯一的存储手段。但是现在浏览器支持各种各样的存储方式,cookie渐渐被淘汰。新的浏览器API已经允许开发者将数据存储到本地,如使用web storage API(本地存储和会话存储)或indexedDB 。
用途:
- 会话状态管理 :如用户登陆状态,购物车,游戏分数或其它需要记录的信息。
- 个性化设置:用户自定义设置,主题等。
- 浏览器行为追踪:跟踪分析用户行为。
创建过程:
服务器发送的响应报文段包含set-cookie首部字段,客户端得到响应报文后把Cookie内容保存到浏览器中。
客户端之后对同一服务器发送请求时,会从浏览器中取出Cookie信息并通过cookies请求首部字段发送给服务器。
分类:
- 会话期cookie: 浏览器关闭后被自动删除,也就是说仅在会话期有效。
- 持久性cookie: 指定一个特定的过期时间(expires)或者有效期(max-age)之后就成为了持久性的
JS中如何获取Cookie
通过Document.cookie 属性可创建新的Cookie,也可通过该属性访问非HttpOnly标记的Cookie
document.cookie="yummy_cookie=choco";
document.cookie="tasty_cookie=strawberry";
console.log(document.cookie);
Secure和HttpOnly
标记为secure的cookie只能通过被https协议加密过的请求发送给服务端。但即便设置了secure标记,敏感信息也不该通过cookie传输,因为Cookie有其固有的不安全性,secure标记也无法提供确实的安全保障。
标记为httponly的cookie不能为js脚本所调用。跨站脚本攻击(XSS)经常使用JS的Document.cookie API来窃取用户的Cookie信息,因此一定程度避免XSS攻击。
作用域:
Domain标识 指定了哪些主机可以接收Cookie。如果不指定,默认当前文档主机(不包含子域名)。如果指定了Domain,则一般包含子域名。
如设置Domain=csdn.net则cookie也包含在子域名 如mp.csdn.net中
Path标识 指定了主机下的哪些路径可以接收Cookie(该URL路径必须存在于请求URL中)。已字符(/)作为路径分割符,子路径也会被匹配。
Session
除了将用户信息通过Cookie存储在用户浏览器中,也可以利用Session存储在服务器端。存储在服务器端的信息更安全。
Session可以存储在服务器上的文件,数据库或者内存中。也可以将 Session存储在redis中,这样效率会更高。
使用Session维护用户登陆状态的过程:
- 用户进行登录时,用户提交包含用户名和密码的表单,放入HTTP请求报文中;
- 服务器验证该用户名和密码;
- 如果正确把该用户信息存储到redis中,它在redis中的key称SessionID
- 服务器返回的响应报文的Set-cookie首部字段包含了这个SessionID,客户端收到响应报文之后将该报文存入浏览器中。
- 客户端之后对同一个服务器进行请求时会包含该Cookie值,服务器收到后会取出SessionID,从redis中取出用户信息,执行业务操作。
需要注意SessionID的安全问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的SessionID。此外,还需要经常重新生成SessionID。在对安全性要求极高的场景下,如支付操作,除了使用SessionID管理用户状态之外,还需要对用户进行重新验证。如验证码等形式。
浏览器禁用Cookie
此时就无法使用Cookie来保存用户信息,只能使用Session。除此之外,不能再将SessionID存放到Cookie中。而是使用URL重写技术,将SessionID 作为URL的参数进行传递。
Cookie与Session的选择
- Cookie只能存储ASCII码字符串,为Session可以存取任何类型的数据,因此再考虑数据复杂性时首选Session;
- Cookie存储在浏览器中,容易被而已查看。如果非要将一些隐私数据存在cookie中,可以将Cookie值进行加密,然后在服务器进行解密。
- 对于大型网站,如果用户所有信息都存储在Session中,那么开销是非常大的,因此不建议将所有用户的信息存储到Session中。
缓存:
优点:
- 缓解服务器压力
- 降低客户端获取资源的延迟:缓存通常位于内存中,读取缓存速度更快。并且缓存在地理位置上也可能比源服务器来的近,例如浏览器缓存。
实现方法:
- 让代理服务器进行缓存
- 让客户端浏览器进行缓存
Cache-Control
Http/1.1 通过cache-Control首部字段来控制缓存。
禁止进行缓存
no-store指令规定不能对请求或响应的任何一部分进行缓存。
cache-control:no-store
强制确认缓存:
no-cache指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效才能使用该缓存对客户端进行响应。
Cache-Control:no-cache
私有缓存和公共缓存
private指令规定了将资源作为私有缓存,只能被单独用户所使用,一般存储在用户浏览器中。
cache-control:private
public指令规定了资源将作为公共缓存,可以被多个用户所使用,一般存储在代理服务器中。
cache-control:public
缓存过期机制:
max-age指令出现在请求报文中,并且缓存资源的缓存时间小于该指令指定的时间,那个就能接收该缓存。
max-age指令出现在响应报文中,表示缓存资源在缓存服务器中保存的时间。
cache-control:max-age=31536000
expires首部字段也可以用于告知缓存服务器该资源什么时候会过期。
- 在http/1.1中,会优先处理max-age指令。
- 在http/1.0中,max-age指令会被忽略掉。
缓存验证
需要先了解Etag首部字段的含义,它是资源的唯一标识。url不能唯一表示资源。如http://www.google.com/ 有中文和英文两个资源,只有Etag才能对这两个资源进行唯一标识。
可以将缓存资源的Etag值放入If-None-Match首部,服务器收到该请求后,判断缓存资源的Etag值和资源的最新ETag值是否一致,如果一致则表示缓存资源有效。
Last-Modified首部字段也可以用于缓存验证,它包含在源服务器发送的响应报文中,指示源服务器对资源的最后修改时间。但是它是一种弱校验器,只能精确到一秒,一般都是Etag的备用方案。如果响应首部字段里包含这个信息,客户端可以在后续的请求中带上If-Modified-Since来验证。服务器只在所请求的资源在给定日期时间之后在对内容进行过修改的情况下才会返回资源。如果请求的资源从那时起未经修改,那么返回一个不带消息主体的304
连接管理
短连接与长连接
当浏览器访问一个包含多张图片的html页面时,除了请求访问的html页面资源,还会请求图片资源。如果每进行一次http通信就要新建一个tcp连接,那么开销会很大。
长连接只需要建立一次tcp连接就能进行多次http通信。
- 从http/1.1开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用
Connection:close;
- 在http1.1 之前是默认是短连接的,如果需要使用长连接,需要由客户端使用
Connection:keep-alive
流水线:
默认情况下,http请求是按顺序发出的,下一个请求只有在当前请求收到响应之后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
流水线是在同一条长连接上发出连续的请求,而不用等待响应返回,这样可以避免连接延迟。
内容协商
类型
1,服务端驱动型
客户端设置特定的https首部字段,如Accept,Aceept-Charset,Accept-Encoding,Accept-Language,Content-Languag,服务器根据这些字段返回特定的资源。
它存在如下问题:
- 服务器很难知道客户端浏览器的全部信息。
- 客户端提供的信息相当冗余(http/2 协议的首部压缩机制缓解了这个问题) 并且存在隐私风险(http指纹识别技术)
- 给定的资源需要返回不同的展现形式,共享缓存的效率会降低,而服务端实现会越来越复杂。
2,代理驱动型
服务器返回300 或者 406 客户端会从中选最合适的那个资源。
Vary
Vary:accept-Language
在使用内容协商的情况下,只有当缓存服务器中缓存内容满足协商条件时,源服务器返回的响应包含vary:accept-language内容,缓存服务器对这个响应进行缓存之后,在客户端下一次访问同一个url资源,并且accept-language与缓存中的对应的值相同时才会返回该该缓存。
内容编码
内容编码将实体主体进行压缩,从而减少传输的数据量。
常用的内用编码有:gzip,compress,deflate,identity。
浏览器发送Accept-Encoding首部,其中包含有它所支持的压缩算法,以及各自的优先级。服务器则从选择一种,使用该算法对响应的消息主体进行压缩,并且发送content-encoding首部来告知浏览器,服务器选择了哪一种算法。由于该内容协商过程时基于编码类型来选择资源的展现形似的,在响应的Vary首部至少要包含Conntent-encoding。
范围请求:
如果网络出现中断,服务器只发送了一部分数据,范围请求可以使客户端只请求服务器未发送的那部分数据,而从避免服务器重新发送所有数据。
1,Range
在请求报文中添加Range首部字段指定请求的范围。
请求成功,服务器返回的响应包含206状态码。
2,Accept-Ranges
响应首部字段Accept-Ranges用于告知客户端是否能够处理范围请求,可以处理使用bytes,否则使用none。
3,响应状态码
- 在请求成功的情况下,服务器会206
- 在请求返回越界的请求下,服务器会返回416
- 在不支持范围请求的情况下,服务器返回200OK状态码。
多部分对象集合
一份报文主体可包含有多种类型的实体同时发送,每个实体之间用boundary字段定义的分隔符进行分割,每个部分都可以有首部字段。
如上传多个表单时可以使用如下方式。
虚拟主机
http/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名,并且在逻辑上可以看成多个服务器。
通信数据转发
1,代理
代理服务器接收客户端的请求,并且转发给其它服务器。
使用代理的主要目的:
- 缓存
- 负载均衡
- 网络访问控制
- 访问日志记录
代理服务器分正向代理和反向代理两种:
- 用户察觉得到正向代理得存在。
- 反向代理一般位于内部网络中,用户察觉不到。
2,网关
与代理服务器不同的是,网关服务器会将http转换为其它协议进行通信,从而请求其它非http服务器的服务。
3,隧道
使用SSL等加密手段,在客户端和服务器之间建立一条安全的通信线路。