应用层协议HTTP

目录

HTTP协议简介

URL和uri

Http请求和应答格式

请求

应答

状态码

重定向

请求方法

会话管理


HTTP协议简介

HTTP(HyperText Transfer Protocol,超文本传输协议)是网络中一个至关重要的协议,它定义了客户端(如浏览器)与服务器之间的通信,以交换或传输超文本。

HTTP协议是客户端与服务器之间通信的基础。客户端通过HTTP协议向服务器发送请求,服务器收到请求后处理并返回响应。HTTP是一个无连接、无状态的协议,即每次请求都要建立新的连接,且服务器不会保存客服端的状态信息。

Http本质和浏览器底层,用的都是TcpSocket,用的都是ip+port的进程间通信机制。

URL和uri

在我们用网络进行资源搜索时,通常会用一个网址来进行搜索,这个网址其实就是URL,即统一资源定位符,如下所示:

首先,URL第一部分就是所用到的协议,这里为https。

第二部分"www.example.jp"为对应的域名,本质就是ip地址,访问目标服务器,只能用ip地址,这是因为计算机只认ip地址,浏览器只不过在这里向域名解析服务器发送DNS请求,域名解析服务器会将对应的ip地址返回给浏览器,然后再发起请求,同样的,向域名解析服务器发送请求,同样需要地址,因此,在浏览器内部,会内置一个域名解析服务器的地址,这个地址为8.8.8.8。

第三部分是服务器端口号,绑定的端口号为80,可以被省略。

第四部分是对应的文件路径,可以找到对应的文件并返回,HTTP本质就是为了获取服务器上的文件内容。通过IP+目标文件地址就能标识唯一,在全网中定位找到这个文件,随后再请求和指定端口绑定的服务器进程,得到数据。而uri为统一资源标识符,它更加强调资源的唯一性,URL是一特殊的uri。

第五部分是URL传参,这部分是要传送给服务器的参数。

Http请求和应答格式

请求

http的请求如下所示:

第一行为请求行,第二行到空行之前为请求报头,第三部分为空行,前三行为报头,第四部分为请求正文,该部分为有效载荷,该部分是可选的,通过空行,分离报头和有效载荷。如下所示:

其中,前三部分都是以行为单位保存在Http的报文段中。

请求行以空格为单位被分成了三列,请求方法最常见的是get和post,get为从服务器中获取数据,post为向服务器推送数据;第二部分为URI,表示访问目标服务器目标端口号的特定的资源路径,第三个为客户端的HTTP的版本,最常用的为http/1.1。

第二行到空行之前,每一行都是Key:Value的形式,表示请求报头里涵盖的相关属性信息。

根据请求报文,接收方必须要解决两个问题,首先是如何确保请求报文读完,其次如何反序列化。对于第一个问题,接收方首先可以做到将报头读完,读到连续的两个换行符即可把报头读完,同时请求报头里面会包含一个属性------Content-Length,这里面记录着有效载荷的长度。反序列化以行做为分隔符进行反序列化即可。

请求报头的常见属性如下:

Host:所请求的主机,如果是域名就显示域名,如果是主机就显示主机

Content-Length:请求正文的长度

Content-Type:正文部分内容的类型

User-Agent:客户端类型,通常代表浏览器所对应的类型,通常在请求中携带,应答中没有

Referer:当前页面是从哪个页面跳转过来的

Location:搭配3xx状态码使用,告诉客户端接下来去哪里访问

Cookie:用于在客户端存储少量信息,通常用于实现会话(session)的功能

在用http请求时,如果在端口号后面什么路径都不加,uri默认为"/",这个为web根目录,后面的路径表示该主机唯一的一个文件资源,域名表示主机唯一性,路径表明文件唯一性。通常网络服务,有自己的web根目录,在项目源代码对应的同级目录下,还会有默认的首页,这个首页的文件名默认为index.html。http超文本请求的本质,其实就是通过网络服务器把Linux机器上,特定目录下的文件以http应答的方式返回给client(浏览器或者app)

应答

响应报文如下所示:

响应报文的结构和请求报文类似,第一行状态行中HTTP版本的表示的是服务端的HTTP版本,状态码为服务器的一个应答,HTTP中规定,发起请求获得应答时,不管成功还是失败,如果网络没问题,服务器没有挂掉,都必须有应答,如果请求成功,就会返回2xx状态码,如果请求失败,就会返回对应的错误码,如404。应答中没有Content-Length属性,这是因为响应正文是有比较确定的格式的,格式内部就会有对应的相关属性,浏览器可以进行解析,但请求中上传的文件时多样的,长度不是定长的,也没有格式,所以必须要有Content-Length。

状态码

状态码描述就是对状态码含义对应的解释。HTTP常见的状态码如下表:

|-----|-------------------------|---------------|
| | 类别 | 原因短句 |
| 1XX | Informational(信息性状态码) | 接收的请求正在处理 |
| 2XX | Success(成功状态码) | 请求正常处理完毕 |
| 3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
| 4XX | Client Error (客户端错误状态码) | 服务器无法处理请求 |
| 5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |

重定向

在Http中,存在一种特殊的状态码,这种特殊的状态码为重定向,重定向就是从一个页面跳转到另外一个页面的过程,重定向状态码有301,302还有307等。301为Moved Permanently,代表永久重定向,302为Found,为临时重定向,临时重定向不会修改客户端的认识,只是会进行额外的页面跳转;永久重定向会改变客户端的认识。

客户端向服务器发送请求时,服务器会给客户端返回一个3xx状态码,同时会添加一个Location的报头,这个报头为要重定向到的新的网址,客户端收到对应的状态码和Location,浏览器识别到状态码为3xx,会向对应的站点发送新的二次请求。客户端每次对于新的地址不做记录,就是临时重定向,如果客户端若更新本地书签,下一次访问时直接去访问新的网站,此时就为永久重定向。

302临时重定向往往会在网站登录成功或注册成功时出现,301永久重定向通常会在老网站域名改变时出现。报头里面会有一个属性Location,通常搭配3xx状态码使用,告诉客户端接下来要去哪里访问。

请求方法

HTTP中有很多的请求方法,但是最常用的就是get和post方法,如果想获取资源,则使用get方法,如果想将客户端的数据推送到服务器端,如登录时将用户的账号密码推送到服务器进行验证,常见的方法为post。

当用户要和服务器进行交互时,前端网页中会有一个表单,如下所示:

html 复制代码
<form action="#" method="GET">
    <label for="username">用户名:</label><br>
    <input type="text" id="fname" name="name"><br>
    <label for="passwd">密码:</label><br>
    <input type="password" id="lname" name="passwd"><br><br>
    <input type="submit" value="Submit">
</form>

在这个表单中,最重要的一个是action,另外一个是method,method默认为get方法,提交表单时,若方法为get方法,那么就是通过URL来传参的,另外一个为action,这个代表要将数据提交给http上的哪一个服务,用户填写表单后,浏览器会自动提取表单的内容并构建带参数的http request,如下所示:

同时,浏览器端会形成121:4.21.28:8080/a/b/c?name=aaa&passwd=123456,形成新的URL后提交参数,资源和参数之前用?隔开,参数之间用&隔开,相当于浏览器将后面的参数提交到对应的服务中去。因此,get方法可以用来进行静态资源的获取,同时也可以向目标服务器传递参数。

若采用post方法,请求信息如下所示:

此时,参数放在了正文部分,浏览器端会形成121:4.21.28:8080/a/b/c,POST方式可以用来向目标服务器传参,传参的方式是通过正文部分传参。

因此,HTTP中的URI可以是Linux Web根目录下存在的一个文件路径(静态资源访问),如视频、音频、html等,也可以把它当做一个字符串,用来请求http server中对应的服务,这个字符串往往以路径形式体现,只不过,这个路径不能在web根目录下存在,这种服务为动态服务。

会话管理

当我们登录网站时,在很长时间内,都会在线,这种方式可以减少用户频繁登录的功能。但HTTP是无状态、无连接的,那么是怎么记住用户的信息的呢?

其中一种方案,在用户登录成功时,服务器在应答的报头中添加属性:Set-Cookie,其基本的格式如下:

复制代码
Set-Cookie: <name>=<value>
其中name是Cookie的名称,<value>是Cookie的值

这里面包含了用户名和密码,客户端会在特定目录中保存用户名和密码,相当于向客户端写入数据,这个数据就是cookie,当用户再次发送请求时,或自动携带Cookie属性中的信息,服务器解析HTTP请求时,会得到cookie中的用户名和密码,并自动进行认证。cookie的保存方式,通常有两种,一种是写入到文件中,这种可以持久化存储;另外一种方式是保存在内存中。同时,Set-Cookie中也存在一个过期时间,当过期时间到了,将相关的cookie移除。

但是这种问题存在一个问题,如果黑客获取到了用户的Cookie信息,就会存在"盗号"问题,或者其它安全问题。第二种方案是将相关的结构化信息保存在服务端,保存方式就是将以文件形式保存,并将文件命名成一个唯一的数字,用户的基本信息此时称为session,对应的文件名为session id,应答时的Set-Cookie属性对应的值为session id,浏览器将session id保存下来,每次请求时会自动携带session id。该方案解决的用户数据泄露问题,但是冒充用户身份的问题还没有彻底解决,这个问题光靠http无法彻底解决,而应该靠更上层来解决,可以通过让sessionid失效方式来解决,这种方式的主动权就在服务端,可以更快地发现问题并解决问题。

相关推荐
闻道且行之2 小时前
C/C++ HTTP 服务:常用方法与实现方式全解析
c语言·c++·http·libhv·curl·mongoose·libcurl
深蓝轨迹2 小时前
TCP/IP 网络模型面试核心考点总结01(基础篇)
网络·tcp/ip·面试
YJlio2 小时前
《Windows 11 从入门到精通》读书笔记 1.4.9:全新的微软应用商店——“库 + 多设备同步”把它从鸡肋变成刚需入口
c语言·网络·python·数码相机·microsoft·ios·iphone
YJlio2 小时前
《Windows 11 从入门到精通》读书笔记 1.4.10:集成的微软 Teams——办公与社交的无缝衔接
c语言·网络·python·数码相机·ios·django·iphone
安科士andxe2 小时前
深度解析安科士1X9-1.25G-60Km光模块,为何能成为长距低速通信首选?
网络·5g
路由侠内网穿透2 小时前
本地部署开源网络书签与内容管理工具 Karakeep 并实现外部访问
运维·服务器·网络·数据库·开源
Fairy要carry3 小时前
项目05-手搓Agent之任务通信+任务编排的实现
服务器·前端·网络
正儿八经的数字经3 小时前
从光到电,超节点走出互连“技术岔路”
网络