HTTP详解,输入一个URL,为什么会出现一个web界面

HTTP是什么,哪些地方使用了HTTP呢?

我们使用计算机时,最常用的其实就是输入一个网址,例如www.baidu.com,然后就跳转到百度搜索的界面了。那么为什么我们输入的是一个网址,呈现出的却是一个web界面呢,这就得益于http协议了,Web 界面不会凭空出来,根据 Web 浏览器地址栏中指定的 URL,Web 使用一种名为 HTTP 的协议作为规范,完成从客户端到服务端的一些流程。可以说,Web 是建立在 HTTP 协议上进行通信的

HTTP是什么?

 HTTP:超文本传输协议,是互联网使用最为广泛的一种协议,所有万维网(WWW)文件都必须遵守这个协议.HTTP和TCP/IP协议簇中的众多协议一样,用于客户端和服务器端的通信

什么是超文本?

HTTP传输的内容就是超文本

  • 先来说一下文本:互联网早期的时候只是简单的字符文字,但随着技术发展,文本的涵义已经扩展成了图片,视频,压缩包等,这些在HTTP眼里都是文本!
  • 再来说超文本:超文本就是超越了普通文本的文本,它是文字,图片,视频的混合体。最关键有超链接,能从一个超文本跳转到另一个超文本

HTML就是最常见的超文本,HTML本身是纯文字文件,但是内部使用了很多标签去定义图片、视频、压缩包,经过浏览器的解析,呈现出来的就是一个有文字、画面的网页了

 

HTTP有几个版本?

其实我们现在使用的HTTP协议是20几年前的版本,也就是说作为web文档传输协议的HTTP已经很长时间没有更新了

HTTP/0.9——HTTP于1990年问世,仅支持GET请求方式,并且只可以访问HTML格式的资源,那时候的HTTP并没有作为正式的标准被确立

HTTP/1.0——1996年5月HTTP作为正是标准被公布,相比0.9,1.0版本新增了POST、HEAD请求方式;并且不再局限于HTML格式,根据content-type可以支持多种数据格式,1.0版本的工作方式是短连接(传输一次资源就要建立连接一次)

HTTP/1.1——1997年公布,是目前最主流的HTTP版本,虽然当年HTTP协议是为了解决文本传输的困难,但是现在早已经超出了web这个框架的限制。但是1.1版本最大的变化还是引入了流水线机制和长连接(一次连接即可)

区分URL和URI

URL相信大家都很熟悉,就是我们在浏览器输入的网址,URL全称uniform resource location,统一资源定位符,举个例子——https://baidu.com

URI是uniform resource identifier的缩写,全称统一资源标识符,URI的三个单词的定义为

  • Uniform:统一规定的格式可方便处理多种不同类型的资源
  • Resource:资源的定义是可标识的任何东西。不仅可以是单一的,也可以是一个集合
  • Identifier:标识可标识的对象。也称为标识符

综上,URI就是某个协议方法表示的资源的定位标识符,比如说,采用HTTP协议时,协议方案就是http,除此之外还有ftp、Telnet等,标准URI协议方法有30余种

URI有两种格式

1.相对URI——指从浏览器中基本URI处指定的URL,比如/user/1.jpg

2.绝对URI——使用涵盖时的全部信息

 总结:URI用字符串标识互联网的某处资源,而URL是标识资源的地点,所有url可以看出URI的子集

HTTP请求与响应

在浏览器中输入网址访问某个网站时,浏览器(客户端)会将你的请求封装成HTTP请求传输给服务器站点,服务器收到请求后会组织响应数据封装成一个HTTP响应返回给浏览器,所以HTTP请求一定是从客户端发起的,换句话说,肯定是从客户端开始建立通信的

 什么是HTTP请求报文

HTTP请求报文包含3个部分

  • 请求行——必须在请求报文的 第一行
  • 请求头(主体)——从第二行开始,到第一个空行结束
  • 请求体(通常以键值对{key:value}传输数据)——和请求头之间存在一个空行

 请求行开头的POST表示访问服务器的类型,也叫作方法。随后的/form/login是要访问的资源对象,也叫作请求URI,最后的就是HTTP协议版本号,用来提示服务器客户端使用的HTTP版本

这个HTTP请求的意思就是:请求访问某台HTTP服务器上的/form/login处的页面资源,并附带参数name=veal,age=37

注意,无论是 HTTP 请求报文还是 HTTP 响应报文,请求头/响应头和请求体/响应体之间都会有一个空行,且请求体/响应体并不是必须的。

 HTTP请求方法

常见的HTTP方法有:GET,POST,HEAD,PUT,DELETE,OPTIONS,CONNECT,TRACE,但是较常用的就前面4个

1.GET获取资源

GET方法用来请求访问被URI识别的资源。指定的资源经服务器端解析后返回响应内容

 使用GET请求的例子

2.POST传输实体数据

POST主要就是用来传输数据,GET是用来获取某个资源(和名字很符合)

3.PUT传输文件

PUT方法用来传输文件,由于其自身不带验证机制,任何人都可以上传 ,所以存在安全性问题,一般不使用

4.HEAD获取报文首部

和GET方法类似,但是不返回报文主体部分,主要就是用于确认URI的有效性以及资源的更新日期

 

5.DELETE删除文件

和PUT相反,用来删除文件,并且同样是不安全的(HTTP就是不保证安全的),按照请求的指定URI删除资源

 

 6.OPTIONS查询支持的方法

用于获取当前URI所支持的方法,若请求成功,会在HTTP响应头中包含一个名为Allow的字段,值是所支持的方法,如“GET,POST”

HTTP请求头

请求头就是用来补充的附加信息、客户端信息、对响应内容的优先级等等,常见的请求头有

1.Referer——表示这个请求是从哪个 URI 跳过来的。比如说通过百度来搜索淘宝网,那么在进入淘宝网的请求报文中,Referer 的值就是:www.baidu.com。如果是直接访问就不会有这个头。这个字段通常用于防盗链。

 2.Accept——告诉服务端所支持的响应数据类型(对应的响应报文也会有一个对应的content-type表示返回的数据类型,如果这两个不一致,就会报错)

 上图中的 text/plain;q = 0.3 表示对于 text/plain 媒体类型的数据优先级/权重为 0.3(q 的范围 0 ~ 1)。不指定权重的,默认为 1.0。

常见的数据格式类型:

3、Host:告知服务器请求的资源所处的互联网主机和端口名,这个字段是HTTP1.1版本中唯一要求必须要包含在请求头中的字段(告诉服务器要去哪里找资源给我)

4.Cookie:客户端的cookie就是通过这个报文传给服务器的

Cookie: JSESSIONID=15982C27F7507C7FDAF0F97161F634B5

5.Connection:表示客户与服务端的连接类型(keep-alive表示长连接,close是以关闭)

6.Content-length:请求体的长度

7.Accept-Language:浏览器告知服务器自己支持的语言

8.Range:对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围

 HTTP响应报文(和请求报文一样三部分)

  • 响应行(必须在 HTTP 响应报文的第一行)
  • 响应头(从第二行开始,到第一个空行结束。响应头和响应体之间存在一个空行)
  • 响应体

 在响应行开头的HTTP1.1表示版本,200是状态码,OK是原因短语

HTTP状态码(重要)

HTTP状态码负责表示客户端HTTP请求的返回结果,标记服务器端处理是否正常、通知出现的错误等工作

 状态码是三位数,第一个数字决定响应的类别

2xx:请求正常处理完毕

200 OK:客户端请求成功

204 No Content:无内容,服务端成功处理,但无内容返回。一般用在客户端给服务器发送信息,服务器不用返回数据的情况

 

206 Partial Content:服务器已经完成了部分GET请求(客户端进行了范围请求),响应报文中包含Conten-Range指定范围的实体内容 

 

 3xx:需要进行附加操作以完成请求(重定向)

301 Moved Permanently:永久重定向,表示请求的资源已经永久的移动到了别的位置

302 Not Found:临时重定向,表示请求的资源临时搬到了别的位置

303 See Other:也是临时重定向,应使用GET定向获取请求资源,303功能和302一样,区别在于303要求客户端用GET请求访问

304 Not Modified:表示客户端发送附带条件的请求(GET方法请求报文中的IF...)时,条件不满足。返回304时,不包含任何响应实体,虽然304是3xx,但是和重定向无关系

307 Temporary Redirect:临时重定向,和302一样,POST不会变成GET

 4xx:客户端错误

400 Bad Request:客户端请求有语法错误、服务器无法理解

401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authentic报头域一起使用

403 Forbidden:服务器收到请求,但是拒绝提供服务

404 Not Found:请求资源不在,比如输入了错误的URL

415 Unsupported media type:不支持的媒体类型

 5xx:服务器端错误、服务器未能实现合法的请求

500 Internal Server Error:服务器发生不可预期的错误

503 Server Unavailable:服务器当前处于超负载或者停机维护了,暂时不可以处理客户端请求,一段时间后可以恢复正常

HTTP响应头

响应头也是用键值对{k:v}用于补充响应的附加信息,服务器信息和客户端的附加要求等 

这里的Location字段,可以将响应接收方引导至某个URI位置不同的资源,通常来说配合3xx状态码使用,告知客户端需要重定向。

HTTP的连接方式

1.短连接(非持久)

在HTTP/1.0中,客户端和服务端每进行一次HTTP会话,就建立一次连接,任务结束就断开。当客户端浏览器访问的某个HTML或其他类型web页中包含其他的web资源(JavaScript文件,图像,CSS等),每遇到一个这样的资源,浏览器就重新建立一个HTTP会话。这种方式称为短连接

那么每次HTTP请求都要建立一次连接,由于HTTP是基于TCP/IP协议,那每次连接都要经历

TCP三次握手-TCP四次挥手的开销。

这种方式是存在很大的弊端的,假设访问一个含有很大图片的HTML页面,每请求一张图片就建立一次连接,造成无所谓的TCP连接或断开,大大增加了通信量的开销

2.长连接(持久连接)

从HTTP/1.1开始,默认使用长连接(keep-alive),使用长连接的HTTP协议,会在响应头加入Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP的长连接短连接实质就是TCP协议的长连接和短连接

3.流水线(管线化)

默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到响应之后才会被发出。由于受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。

持久连接使得多数请求以流水线(管线化 pipeline)方式发送成为可能,即在同一条持久连接上连续发出请求,而不用等待响应返回后再发送,这样就可以做到同时并行发送多个请求,而不需要一个接一个地等待响应了。(像队列一样)

 无状态的HTTP

 HTTP是无状态的协议,也就是说它不对之前发生过的请求和响应状态进行管理,即无法根据之前的状态进行本次请求的处理

这样就会出现一个问题,如果HTTP无法记住用户的登录状态,那每次页面的跳转都会导致用户需要重新登录一次。(当然无状态也有其优点,因为无需保存状态,所以CPU和内存消耗较少,而且简单,所以应用广泛)

在保留无状态协议特征的同时,又要解决其带来的问题,方案很多种,最常用简单的就是Cookie

Cookie通过在请求和响应报文中写入Cookie信息来控制客户端状态,具体的说,Cookie会根据从服务器端发送的响应报文中的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往服务器发送请求时,客户端自动在请求报文中加入Cookie值发送,服务器收到客户端发送过来的Cookie后,会检查是哪一个客户端发来的连接请求,然后对比服务器上的记录,得到之前的客户端状态信息

通俗的说,客户端和服务器第一次建立连接时,服务器会给客户端发送一个装有客户端状态信息的身份证(Cookie),后续客户端请求服务器的时候带上身份证(Cookie),服务器就认得了

1.没有运用Cookie的请求(第一次建立连接)

对应的请求报文

GET /reader/ HTTP/1.1
Host: baidu.com
* 首部字段没有 Cookie 的相关信息

 响应报文

HTTP/1.1 200 OK
Date: Thu, 12 Jul 2020 15:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226; path=/; expires=Wed, 10-Oct-12 15:12:20 GMT>
Content-Type: text/plain; charset=UTF-8

2.第2次之后的请求(带有Cookie)

对应的请求报文

GET /image/ HTTP/1.1
Host: baidu.com
Cookie: sid=1342077140226

HTTP断点续传

所谓断点续传指的就是下载传输文件可以中断,之后重新下载时可以接着中断的地方开始下载,而不必从头开始下载。断点续传需要客户端和服务器都支持

这个功能的实现并不困难,原理其实就是HTTP请求头字段中的Range字段和响应头的

Content-Range字段,客户端一块一块的请求数据,最后将下载好的数据块拼接成完整的数据。打个比方,浏览器请求服务器上的一块服务,所发出的请求如下

设域名为www.baidu.com,文件名为down.zip

GET /down.zip HTTP/1.1 
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- 
excel, application/msword, application/vnd.ms-powerpoint, */* 
Accept-Language: zh-cn 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) 
Connection: Keep-Alive 

服务器收到请求之后,按要求寻找文件,提取文件信息,然后返回给浏览器,响应信息为

200 
Content-Length=106786028 
Accept-Ranges=bytes 
Date=Mon, 30 Apr 2001 12:56:11 GMT 
ETag=W/"02ca57e173c11:95b" 
Content-Type=application/octet-stream 
Server=Microsoft-IIS/5.0 
Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT 

那如果要实现断点续传,客户端应该在发送请求报文时加多一条信息——从何处开始请求数据,比如要求从2000070字节开始

GET /down.zip HTTP/1.0 
User-Agent: NetFox 
RANGE: bytes=2000070- 
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 

其中的RANGE:bytes=2000070-就是表面down.zip这个文件从2000070开始下载,之前的不用传输

服务器收到该信息后,返回信息为

206
Content-Length=106786028
Content-Range=bytes 2000070-106786027/106786028
Date=Mon, 30 Apr 2001 12:55:20 GMT
ETag=W/"02ca57e173c11:95b"
Content-Type=application/octet-stream
Server=Microsoft-IIS/5.0
Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT

响应报文也多了一行——Content-Range,返回的代码也是206而不是200了,代表部分完成了客户端的GET请求。

HTTP的缺点

  • 通信使用明文(不加密),内容可能被窃听
  • 不验证通信对方的身份,因此有可能遭遇伪装
  • 无法证明报文的完整性,所以有可能被篡改

这些问题不仅在 HTTP 上出现,其他未加密的协议中也存在类似问题,为了解决 HTTP 的痛点,HTTPS 应用而生,说白了 HTTP + 加密 + 认证 + 完整性保护就是 HTTPS 协议 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值