一.预备知识
在客户端访问服务端时,要用ip+port,但是在日常用户访问服务端的时候,并不会直接使用ip,而是使用域名,比如:百度(www.baidu,com)。 在浏览器处理时,会将域名解析为对应的ip+port。 http协议默认是使用80端口,如果不指定访问端口号,http协议会自动加上80,https默认时443。
1.1解析url
一、协议方案名
http
表示的是协议名称,表示请求时需要使用的协议,通常使用的是HTTP协议或安全性更高的协议HTTPS。在HTTP的基础上加了一层ssl加密解密层。 常见的应用层协议:
- HTTP(Hyper Text Transfer Protocol):超文本传输协议
- HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer):安全数据传输协议
- FTP(File Transfer Protocol):文件传输协议
二、登录信息
usr:pass
表示的是登录认证信息,包括登录用户的用户名和密码。
三、服务器地址
www.example.jp
表示的是服务器地址,也叫做域名,比如www.alibaba.com
,www.qq.com
,www.baidu.com
。
四、服务器端口号
80
表示的是客户端用哪个端口号连接服务端。HTTP协议和套接字编程一样都是位于应用层的,在进行套接字编程时我们需要给服务器绑定对应的IP和端口,而这里的应用层协议也同样需要有明确的端口号。
五、带层次的文件路径
/dir/index.htm
表示的是要访问的资源在服务端所在的路径。访问服务器的目的是获取服务器上的某种资源,通过前面的域名和端口已经能够找到对应的服务器进程了,此时要做的就是指明该资源所在的路径。
六、查询字符串
uid=1
表示的是请求时提供的额外的参数,这些参数是以键值对的形式,通过&
符号分隔开的。比如我们在百度上面搜索HTTP,此时可以看到URL中有很多参数,而在这众多的参数当中有一个参数wd(word),表示的就是我们搜索时的搜索关键字wd=HTTP
。
七、片段标识符
ch1
表示的是片段标识符,是对资源的部分补充。
如果在搜索关键字当中出现了像/?:
这样的字符,由于这些字符已经被URL当作特殊意义理解了,因此URL在呈现时会对这些特殊字符进行转义。点击查看特殊符号转义规则
二. HTTP简介
1.1前置
HTTP协议又叫做超文本传输协议,是一个简单的请求-响应协议,HTTP通常运行在TCP协议之上。在编写网络通信代码时,我们可以自己进行自定义协议来判断区分一次协议的内容,但实际有很多优秀的工程师早就已经写出了许多非常成熟的应用层协议,其中最典型的就是HTTP协议。
应用层常见的协议有HTTP和HTTPS,传输层常见的协议有TCP,网络层常见的协议是IP,数据链路层对应就是MAC帧了。其中下三层是由操作系统帮我们完成的,它们主要负责的是通信细节。如果应用层不考虑下三层,在应用层自己的心目当中,它就可以认为自己是在和对方的应用层在直接进行数据交互。
下三层负责的是通信细节,而应用层负责的是如何传输/解析 发走/发来的数据,两台主机在进行通信的时候,应用层的数据能够成功交给对端应用层,因为网络协议栈的下三层已经负责完成了这样的通信细节,而如何传输/解析 发走/发来过来的数据就需要我们去定制协议,这就是HTTP协议的工作。
HTTP是基于请求和响应的应用层服务,作为客户端,你可以向服务器发起request(请求),服务端收到这个request(请求)后,服务端的http协议会对这个request(请求)做数据分析,得出你想要访问什么资源,然后服务器再构建response(响应),完成这一次HTTP的请求。这种基于请求-响应这样的工作方式,我们称之为cs模式,其中c表示client,s表示server。
1.2.HTTP请求协议格式
HTTP请求由以下四部分组成:
请求行:[请求方法]+[url]+[http版本]+\r\n
请求报头:请求报头由多行请求行组成。表示请求的属性,这些属性都是以key: value的形式按行陈列的最后加上\r\n。
空行:遇到空行表示请求报头结束。
请求正文:请求正文允许为空字符串,如果请求正文存在,则在请求报头中会有一个Content-Length属性来标识请求正文的长度。
如何将HTTP请求的报头与有效载荷进行分离?
我们可以根据HTTP请求当中的空行来进行分离,当服务器收到一个HTTP请求后,就可以按行进行读取,如果读取到空行则说明已经将报头读取完毕,再读取数据读取的就是有效数据。
怎么确保读取到的数据是一个完整的数据?
请求报头中有一个字段叫Content-Length(正文长度),正文读取正文长度个字节数据就代表把一整个请求/响应报文的正文有效数据全部读取到了。
为什么HTTP的请求和响应报文的请求行都有HTTP协议版本?
目的是为了让客户端和服务端协商,让对方知道我方使用的是HTTP的哪个版本,从而防止出现不同版本导致不兼容的情况。
1.3.HTTP请求行的中的请求方法
HTTP常见的方法如下:
其中90%情况下使用的是GET方法和POST方法,而在这90%中,GET方法占80%。
GET方法一般用于获取某种资源信息,而POST方法一般用于将数据上传给服务器。但实际我们上传数据时也有可能使用GET方法,比如百度提交数据时实际使用的就是GET方法。
GET方法和POST方法都可以带参: GET方法是通过url传参的。
POST方法是通过正文传参的。
从GET方法和POST方法的传参形式可以看出,POST方法能传递更多的参数,因为url的长度是有限制的,POST方法通过正文传参就可以携带更多的数据。 使用POST方法传参更加私密,因为POST方法不会将你的参数回显到url当中,此时也就不会被别人轻易看到。不能说POST方法比GET方法更安全,因为POST方法和GET方法实际都不安全,要做到安全只能通过加密来完成。
通过Postman分别验证了使用GET和POST请求方法,url处于不同的位置。
1.4. HTTP的状态码
最常见的状态码,比如200(OK),404(没有找到),403(请求权限不够),302(临时重定向),301(永久重定向),504(解析错误)。
Redirection(重定向状态码)
重定向需要配合Location字段,Location字段是HTTP报头当中的一个属性信息,将该字段设置为重定向的地址,该字段表明了你所要重定向到的目标网站。重定向就是通过服务端响应报文中指定其他url,让客户端浏览器访问指定的第三方地址,此时这个服务器相当于提供了一个引路的服务。
重定向又可分为临时重定向和永久重定向,其中状态码301表示的就是永久重定向,而状态码302和307表示的是临时重定向。
临时重定向和永久重定向本质是影响客户端的标签,决定客户端是否需要更新目标地址。如果某个网站是永久重定向,那么第一次访问该网站时由浏览器帮你进行重定向,但后续再访问该网站时就不需要浏览器再进行重定向了,此时你访问的直接就是重定向后的网站。而如果某个网站是临时重定向,那么每次访问该网站时如果需要进行重定向,都需要浏览器来帮我们完成重定向跳转到目标网站。
1.4. HTTP常见的Header
HTTP常见的Header如下: Content-Type:数据类型(text/html表示是个html超文本,text/plain表示是个纯文本等等)。
Content-Length:正文的长度。
Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上。
User-Agent:声明用户的操作系统和浏览器的版本信息。
Referer:当前页面是哪个页面跳转过来的。
Location:搭配3XX状态码使用,告诉客户端接下来要去哪里访问。
Cookie:用于在客户端存储少量信息,通常用于实现会话(session)的功能。 Connection:支持长连接还是短连接。
Referer
Referer代表的是你当前是从哪一个页面跳转过来的。Referer记录上一个页面的好处一方面是方便回退,另一方面可以知道我们当前页面与上一个页面之间的相关。
Connection
我方是否支持长连接,如果设置为keep-alive就代表支持长连接。长连接和短连接的区别在于:短连接是客户端和服务端双方在进行一次完整的请求-响应完毕后自动断开连接,如果想要再次进行数据的交互,需要双方再次建立连接。而长连接是cs双方在进行一次连接后,可以进行多次的请求-响应。HTTP1.0只支持短连接,1.1及以上才支持长连接。
如果一个连接建立后客户端和服务器只进行一次交互,就将连接关闭,就太浪费资源了,因此现在主流的HTTP/1.1是支持长连接的。所谓的长连接就是建立连接后,客户端可以不断的向服务器一次写入多个HTTP请求,而服务器在上层依次读取这些请求就行了,此时一条连接就可以传送大量的请求和响应,这就是长连接。
Cookie和Session
HTTP协议默认是无状态的,和HTTP会对登录的用户保持会话功能。什么意思呢?首先解释前者:每个HTTP协议都是独立的,服务端在处理客户端发来的请求时,不会自动识别哪些HTTP请求是来自于同一个客户端,因此就需要用到额外的机制记录客户端请求客户端获取的资源,就会用到Cookie和Session。比如:我们在淘宝购物时,将商品加入到购物车和付款。付款和加入购物车不是同一个请求,因此,在付款请求之前就要提前记录好哪些商品几经加到了购物车,就要用到Cooike。
对登陆保持会话功能意思是,登录了某个账号,在一段时间内就不用再次登录了。在用户进行登陆操作后,服务端会为这个客户端创建一个Session,Session有自己的一个ID,Session里面保存了客户端输入的账号密码,服务端会用先描述再组织的方法将所有客户端的Sesson组织起来,Session的ID会发送给客户端,客户端会将这个ID保存到自己的Cooike文件中,等下次访问时,会将Cookie中的内容通过请求报文发给服务端,服务端在通过客户端发来的ID编号,遍历自己的Session表,如果能找到,就不用输入密码了。如果找不到,就302临时重定向。这样,在登录了一段时间内就不用再次登录了。
客户端保存Cookie的方式有两种,一种是文件级别,一种是内存级别。 内存级别:浏览器是个进程,进程可以在堆区new空间,将自己的Cookie文件内容存储在堆区。 文件级别:保存到磁盘中。
内存级别关闭了计算机在启动就消失不见了,文件级别还会存在。