URI(uniform resource identifier统一资源标识符
URI包括URL和URN,
URL是统一资源定位符uniform resource locator
URN 统一资源名称uniform resource name
请求报文分为请求行、请求头和请求体
请求行 = 方法 URL 版本
方法有POST是用来提交数据或者文件的。
比如说在支付场景中,客户端需要把我是谁,我要支付多少,我要买啥告诉服务器,这就需要使用POST方法。
再比如在云计算里面,我们在服务端,要提供一个基于HTTP协议的创建云主机的API(所谓的API,就可以理解是一个方法),也会用到POST方法。这个时候往往需要将我要创建多大的云主机?多少CPU、多少内存、多大硬盘、这些信息放在JSON字符串里,通过POST方法告诉服务端.
我们在编程时,就是把数据部分放在一个JSON数组里面。而在HTTP请求报文里面,也就是直接把这个JSON数组放在HTTP报文的请求体中,然后我们在服务端编程。也是接收这些数据,依据key来接收其value,然后把收到的数据作为参数,给一个方法调用(这个方法就是API),经过方法调用之后会产生响应信息。然后再把响应信息传给客户端。
还有一种方法叫做是PUT.就是向指定资源位置上传最新内容。但是服务器一般是禁用PUT方法和DELETE方法。所以PUT和POST功能差不多,一般可能不用PUT.
删除一个云主机,就会使用delete方法。
我们把请求行中的数据称为首部字段
Accept-Charset,表示客户端接收的字符集。防止传过来的是其他的字符集,以致出现乱码。
Content-Type 比如我们进行POST请求,如果正文是JSON格式,那么我们就把这个值设为POST.
响应报文 = 状态行 + 响应头和响应体。
状态码:301永久性重定向、302临时性重定向
当一个浏览器访问一个包含多个图片的HTML页面时,除了请求访问的HTML页面资源,还会请求图片资源。
HTTP1.0是一个TCP连接只能处理一个HTTP请求。
什么是HTTP长连接和短连接
长连接就是建立一次TCP连接,就能进行多次HTTP通信,如果是短连接的话,就是建立一次TCP连接,只能进行一个HTTP通信。
HTTP1.1默认是长连接的,如果要断开,则要设置Connection:close(在请求头里)
HTTP1.0默认是短连接的,如果需要使用长连接,则Connection:keep-alive
HTTP协议的请求报文的实体报文通常是JSON格式的。
流水线技术Pipeline (1.1采用流水线技术,不过好像没什么用)
默认情况下,HTTP请求是按顺序发出的,下一个请求只有在当前请求收到响应后才会发出,由于受到网络延迟和带宽的限制,在下一个请求送到服务器之前,可能需要等待很长时间。
流水线技术就是在一条长连接上,连续发出HTTP请求,而不用等待响应返回。这样可以减少延迟。
Cookie?
为什么要引入Cookie,是因为HTTP协议是无状态的。
HTTP1.1引入了Cookie来保存状态信息。
Cookie是服务端产生,保存在客户端,然后客户端每次请求都得携带cookie,因此会造成额外的开销。
但是随着现代浏览器开始支持各种各样的存储方式,Cookie渐渐被淘汰,新的浏览器API已经允许开发者直接将数据存在本地,如使用Web storage API或者是Indexed DB
Cookie的用途:
1、会话状态管理(如用户登录状态,购物车、游戏分数)2、个性化设置3、浏览器行为跟踪。
那么服务端产生的cookie是怎么传给客户端的呢???
HTTP响应报文的响应体是存储的HTML页面,所以它的cookie是存放在响应报文的响应头中,假如说服务端要存储cookie了,
那么就是set-cookie:XXX
然后客户端就把这些响应头中的所有set-cookie都保存在本地。
然后当浏览器再次请求同一个服务器的时候,就会把cookie传给服务器,怎么传呢?它是把cookie放在请求报文的请求头中
key是cookie,value就是具体的cookie,比如说cookie:xxx
cookie分类:持久性cookkie和会话期cookie,
会话期cookie就是仅仅在会话期有效,浏览器关闭之后就会自动删除。
持久性cookie,就是仅仅指过了过期时间或者是有效期就成了永久性的cookie.
如:Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
path标识指定了主机的哪些目录可以接受Cookie.
5、JavaScript:
浏览器通过document.cookie可创建新的cookie,
document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);
6、标记为HttpOnly的Cookie不能被JavaScript脚本调用,跨站脚本攻击(XSS)常常使用JavaScript的document.cookie API来窃取用户的Cookie信息。因此使用HttpOnly可以在一定程度上避免XSS攻击。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
7、Secure:标记为Secure的Cookie只能被HTTPS协议加密过的请求发给服务端,但即使设置了Secure标记,敏感信息也不应该通过Cookie,因为Cookie有其固有的不安全性。Secure标记也无法提供确实的安全保障。
8、Session
Session是存储在服务端的。存储在服务端的信息更加的安全。
Session可以存储在服务器的文件、数据库和内存中(分布式Session的一种解决方式就是使用redis来保存session)
使用Session维护用户登录状态的过程如下:
1、用户进行登录时,用户提交包含用户名和密码的表单,放在HTTP请求报文中。
2、服务器验证该用户名和密码。(当然了,原来用户肯定注册过了,用户名和密码都保存在数据库中),如果正确就把信息存储在Redis中,它在Redis中的key称为是session-id.
3、服务端返回的HTTP响应报文中就有关于session-id这一项,就是set-cookie:session-id
4、客户端收到响应报文后,把cookie值存在本地。
5、客户端之后对同一个服务器进行请求时会包含该cookie值,服务器收到之后提取出session ID,从redis中提取有用的信息,继续之前的业务操作。
记住用户登录状态就可以这样做。
我们先登录了某个网站,然后关闭浏览器,然后我们再打开这个浏览器访问这个网站,就会把session id 传过去,这样服务器就知道是谁登录了这个网站,这样就不需要我们再次登陆了。
Session ID的安全性很重要,不能被攻击者知道,不然攻击者就可以伪造HTTP请求报文中的set-cookie字段,冒充其他用户登录某个网站,获取该用户的信息。
应该要经常重新生成session id.
9、浏览器禁用cookie。
假如说浏览器禁用cookie的话,那么只能使用session,无法使用cookie来保存用户信息,不能把session id 写入cookie中,而是使用URL重写技术,把Session ID作为URL的参数进行传递。
10、Cookie和Session 的选择:
1、Cookie中只能存储ASCII码字符串,而Session中可以存储任何类型的数据,因此在考虑数据复杂性的时候应该首先考虑Session.
2、Cookie存储在浏览器中,容易被恶意查看,如果非要将一些隐私数据放在Cookie,那么可以对Cookie的值进行加密,然后在服务端进行解密。
3、对于大型网站, 如果用户所有的信息都存在Session中,那么开销是非常大的,因此不建议把所有的用户信息都存放在Session中。
缓存(这里的缓存指的是HTTP缓存)
优点:
1、缓解服务器压力
2、降低客户端获取资源的延迟,缓存通常位于内存中,读取缓存的速度更快,
实现方法:
1、让代理服务器进行缓存。
2、让客户端浏览器进行缓存。
HTTP 1.1通过Cache-Control 首部字段来控制缓存。
no-store 表示不能进行缓存。
Cache-Control : no-store
缓存过期机制:
max-age指令,如果说max-age出现在HTTP请求报文中,如下:
Cache-Control: max-age = 22333
并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。如果在请求报文中是max-age = 0,那么就表示客户端不能接受缓存中的数据。
如果出现在响应报文的响应头中,则表示缓存资源在缓存服务器中保存的时间.
请求头字段 Content-Encoding内容编码字段:这是指的对主体内容的编码方式,对传输的主体进行压缩,从而减少传输的数据量。
如gzip、deflate
注意啦:浏览器会先发送(在请求报文的请求头字段中)发送Accept-Encoding : 其中包含它所支持的压缩算法,以及各自的优先级,服务端会选择一种,使用一种对HTTP响应报文的响应体部分进行压缩。并求使用Content- Encoding来告诉浏览器它使用的哪一种压缩算法。
虚拟主机技术
HTTP/1.1使用虚拟主机技术,使得一台服务器拥有多个域名,并且在逻辑上可以看成是多个服务器。
代理服务器
代理服务器接受客户端的请求,并且转发给其他服务器。
代理服务器的作用:
1、缓存
2、负载均衡
3、网络访问控制
4、访问日志记录
代理服务器分为正向代理和负向代理。
用户察觉的到正向代理的存在,而反向代理一般位于内部网络之中,用户察觉不到。
HTTP是应用层协议,它使用TCP协议,因此在传输之前应该要进行三次握手。
HTTP缓存:
比如我们要浏览一个商品的详情信息,里面有这个商品的价格、库存、图片、商品的图一般是不变的,但是库存数量是会不断变化的。如果我们每次更新库存,都要刷新整个页面,就是所有的一切都从服务器重传,那么服务器的压力就会很大。
在接受方的TCP层,它也会看收到的TCP数据报序列包是不是自己想要的数据报,如果不是就会丢弃。
之前说过HTTP请求报文的请求头的字段中有一个Content-Type就是请求报文主体的内容格式通常是JSON格式
而对于HTTP响应报文,它也有这个字段,有两种格式,JSON格式和HTML格式。
TCP/IP传输就是使用Socket编程。
TCP层一定会检查收到的报文的序列号是不是自己想要的序列号,比如说它上次的确认序号是u,结果你发来的报文的序号比u小,那肯定丢弃。
浏览器作为一个应用进程也一直监听某个端口(随机获取的,应该是不固定的)
当浏览器拿到HTTP报文,发现响应行的状态码是200,表示成功返回,就从响应报文的响应体中把HTML页面取出来,然后浏览器就对HTML页面进行解析,显示网页。