HTTP.
2026/9/12 19:07:19 网站建设 项目流程

一,HTTP

1.1 HTTP是什么

HTTP(全称为"超文本传输协议")是⼀种应用非常广泛的应用层协议

HTTP往往是基于传输层的TCP协议实现的.(HTTP1.0,HTTP1.1,HTTP2.0均为TCP,HTTP3基于 UDP实现)

目前我们主要使用的还是HTTP1.1和HTTP2.0

我们平时打开⼀个网站,就是通过HTTP协议来传输数据的

浏览器就相当于http客户端,不只是浏览器,手机app也用http和服务器通信

注意:https和http的绝大部分功能是一样的,http是基础,而https在此基础上添加了额外的加密功能(带有安全机制的http)

当我们在浏览器中个搜输入一个搜索的"网址"(URL)时,浏览器就给搜狗的服务器发送了⼀个HTTP 请求,搜狗的服务器返回了⼀个HTTP响应.。这个响应结果被浏览器解析之后,就展示成我们看到的页面内容。(这个过程中浏览器可能会给服务器发送多个HTTP请求,服务器会对应返回多个响应,这些响应里就包含了页面HTML,CSS,JavaScript,图片,字体等信息).

所谓"超文本"的含义,就是传输的内容不仅仅是文本(比如html,css这个就是文本),还可以是⼀些其他的资源,比如图片,视频,音频等二进制的数据

1.2 理解"应用层协议"

我们已经学过TCP/IP ,已经知道⽬前数据能从客⼾端进程经过路径选择跨⽹络传送到服务器端进程 IP+Port

可是,仅仅把数据从A点传送到B点就完了吗?

这就好比,在淘宝上买了⼀部手机,卖家[客户端]把手机通过顺丰[传送+路径选择]送到买家[服务 器]手里就完了吗? 当然不是,买家还要使用这款产品,还要在使用之后,给卖家打分评论

所以,我们把数据从A端传送到B端, TCP/IP 解决的是顺丰的功能,而两端还要对数据进行加工处理或者使用,所以我们还需要⼀层协议,不关心通信细节,关心应用细节! 这层协议叫做应用层协议。而应用是有不同的场景的,所以应用层协议是有不同种类的,其中经典协议之⼀的HTTP就是其中的佼佼者

顺丰相当于 TCP/IP 的功能,那么买回来的手机都附带了说明书【产品介绍,使⽤介绍,注意事项等】,而该说明书指导用户该如何使用手机,此时的说明书可以理解为用户层协议

1.3 HTTP协议格式

HTTP是⼀个文本格式的协议,可以通过Chrome开发者工具或者Fiddler抓包,分析HTTP请求/响应 的细节

1.4 抓包工具的原理

Fiddler 相当于⼀个"代理"

浏览器访问sogou.com时,就会把HTTP请求先发给Fiddler,Fiddler再把请求转发给sogou的服务 器。当sogou服务器返回数据时,Fiddler拿到返回数据,再把数据交给浏览器。因此Fiddler对于浏览器和sogou服务器之间交互的数据细节,都是非常清楚的

1.4.1 抓包结果
HTTP请求

这里的字符串就是完整的HTTP请求数据包,如果把这个字符串拷贝下来,通过tcp socket写进去,此时就相当于发送了一个HTTP请求

请求格式

如图可以看出这是按照行组织的,按行组织的文本格式也称为“行文本”

  • 首行:[方法] + [url] + [版本] (这三个之间用空格分割)
  • 方法:描述了这次请求要干什么
  • url:描述了要访问哪个资源
  • Header:请求的属性,冒号空格分割的键值对。每组属性之间使用\n分隔,遇到空行表示Header部分结束(每一行都是一个键值对,用“:空格”来分割,请求头的键值对都是标准约定好的,不能随意修改)
  • Body:空行后面的内容都是Body,Body允许为空字符串。如果Body存在,则在Header中会有⼀个 Content-Length属性来标识Body的长度
  • 空行是请求头的结束标记

所谓的HTTP协议,就是按照特定格式构造了一个字符串,客户端如果把这个字符串写入到tcp socket,服务器就可以通过tcp socket把它读出来,这样的字符串就是HTTP协议

服务器还可以构造另一个特定格式的字符串,也写入到tcp socket中,客户端也可以通过tcp socket把这个字符串读出来,这样的字符串就是HTTP响应

HTTP响应

响应格式
  • 首行:[版本号] + [状态码] + [状态码解释]
  • 状态码:成功还是失败
  • Header:请求的属性,冒号空格分割的键值对。每组属性之间使用\n分隔。遇到空行表示Header部分结束
  • Body:空行后面的内容都是Body。Body允许为空字符串,如果Body存在,则在Header中会有一个 Content-Length属性来标识Body的长度。如果服务器返回了⼀个html页面,那么html页面内容就是在body中.
  • 空行为响应头的结束标记

其中,HTTP传输的是文本(字符串),而响应中的二进制乱码,本质上是HTTP服务器返回的数据进行了压缩(压缩软件内部会有一些算法,对数据进行重新计算,重新编码,就可以保证数据含义相同,体积缩小)

fiddler中有解压缩功能,即decode按钮,可以进行解压缩 => 原始数据

解压如下:

此处响应的body内容正是搜狗首页的html

html:描述结构

css:描述样式

JavaScript:描述行为

为什么HTTP报文中要存在"空行"?

因为HTTP协议并没有规定报头部分的键值对有多少个,空行就相当于是"报头的结束标记",或者是 "报头和正文之间的分隔符"。HTTP在传输层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现"粘包问题"

二,HTTP请求(Request)

2.1 URL

HTTP请求中的URL,URL不是http的一部分,其实是独立于HTTP存在的,URL会给很多种协议提供支持

URL全称为唯一资源定位符,描述了一个资源在网络上的位置

2.2 URL基本格式

平时我们俗称的"网址"其实就是说的URL(UniformResourceLocator统⼀资源定位符).

互联网上的每个文件都有⼀个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。URL的详细规则由因特网标准RFC1738进行了约定.(https://datatracker.ietf.org/doc/html/rfc1738)

举例: https://v.bitedu.vip/personInf/student?userId=10000&classId=100

https协议方案名。常见的有http和https,也有其他的类型(例如访问MySQL时用的是jdbc:mysql)

user:pass登录信息。现在的网站进行身份认证一般都不再通过url进行了,所以现在不会把用户名密码放到url中,一般登录,专门有一个“登陆界面”

v.bitedu.vip服务器地址。此处是一个域名,域名会通过DNS系统解析成一个具体的IP地址

这个服务器地址可以是域名也可以是ip地址

端口号上述的url中端口号被省略了,当端口号省略的时候,浏览器会根据协议类型自动决定使用哪个端口,例如http协议默认使用80端口号,http协议默认使用443端口

(通过浏览器,输入url访问http服务器就得知道对方服务器的端口号是多少)

/personInf/student带层次的文件路径。表示要访问的这个程序管理的哪个资源。服务器组织资源的时候,也是按照“目录结构”形式组织的

userId=10000&classId=100查询字符串。本质是一个键值对结构,键值对之间用&分割,键和值之间使用 = 分割(查询字符串是携带参数,对访问指定资源进行补充说明)(此处的键值对是程序员自己定义的)

片段标识此url中省略了片段标识。片段标识主要用于页面内跳转(一般是文档类的网站会见到片段标识符)

2.3 关于URL encode

query string,由于里面的数据是程序员自定义的,可能会包含各种各样的内容,各种各样的字符

像/?:等这样的字符,已经被url当做特殊意义理解了,因此这些字符不能随意出现

比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义

一个中文字符由UTF-8或者GBK这样的编码方式构成,虽然在URL中没有特殊含义,但是仍然需要进行转义。否则浏览器可能把UTF-8/GBK编码中的某个字节当做URL中的特殊符号

把汉字或者特殊符号,字符编码的每个字节使用十六进制表示出来,使用 % 进行分割

转义的规则如下:将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成 %XY 格式

三,HTTP请求中的方法

3.1 GET 方法

GET是最常用的HTTP方法,常用于获取服务器上的某个资源。在浏览器中直接输入URL,此时浏览器就会发送出一个GET请求,另外,HTML中的link,img,script等标签,也会触发GET请求。

使用JavaScript中的ajax也能构造GET请求

GET 请求通常情况下没有body

GET请求的特点

• 首行的第一部分为GET

• URL的query string可以为空,也可以不为空.

• header部分有若干个键值对结构.

• body部分为空

实际URL的长度取决于浏览器的实现和HTTP服务器端的实现。在浏览器端,不同的浏览器最大长度是不同的,但是现代浏览器支持的长度⼀般都很长。在服务器端,⼀般这个长度是可以配置的.

3.2 POST 方法

POST方法也是⼀种常见的方法,多用于提交用户输入的数据给服务器(例如登陆页面和上传文件)。 通过HTML中的form标签可以构造POST请求,或者使用JavaScript的ajax也可以构造POST请求

POST请求的特点

• 首行的第⼀部分为POST

• URL的query string⼀般为空(也可以不为空)

• header部分有若干个键值对结构.

• body部分一般不为空。body内的数据格式通过header中的由header中的 Content-Type 指定。body的长度由header中的 Content-Length 指定

3.3 GET 和 POST 的区别

get和post没有本质区别,主要的区别体现在使用习惯上,使用get的时候可以替换成post,使用post的时候也可以替换成get

• 语义不同:GET⼀般用于获取数据,POST⼀般用于提交数据.

• GET的body⼀般为空,需要传递的数据通过url中的query string传递,POST的query string⼀般为空,需要传递的数据通过body传递

• GET请求⼀般是幂等的,POST请求⼀般是不幂等的.(如果多次请求得到的结果⼀样,就视为请求是幂等的).

• GET可以被缓存,POST不能被缓存.(这⼀点也是承接幂等性).

补充说明:

• 关于语义: GET完全可以⽤于提交数据,POST也完全可以⽤于获取数据.

• 关于幂等性: 标准建议GET实现为幂等的.实际开发中GET也不必完全遵守这个规则(主流⽹站都有 "猜你喜欢"功能,会根据⽤⼾的历史⾏为实时更新现有的结果.

• 关于安全性: 有些资料上说"POST⽐GET请安全".这样的说法是不科学的.是否安全取决于前端在 传输密码等敏感信息时是否进⾏加密,和GET POST⽆关.

• 关于传输数据量: 有的资料上说"GET传输的数据量⼩,POST传输数据量⼤".这个也是不科学的,标 准没有规定GET的URL的⻓度,也没有规定POST的body的⻓度.传输数据量多少,完全取决于不同浏览器和不同服务器之间的实现区别.

• 关于传输数据类型: 有的资料上说"GET只能传输⽂本数据,POST可以传输⼆进制数据".这个也是 不科学的.GET的query string虽然⽆法直接传输⼆进制数据,但是可以针对⼆进制数据进⾏url encode

3.4 其他方法

• PUT 与POST相似,只是具有幂等特性,⼀般⽤于更新

• DELETE 删除服务器指定资源

• OPTIONS 返回服务器所⽀持的请求⽅法

• HEAD 类似于GET,只不过响应体不返回,只返回响应头

• TRACE 回显服务器端收到的请求,测试的时候会⽤到这个

• CONNECT 预留,暂⽆使⽤

这些⽅法的HTTP请求可以使⽤ajax来构造.(也可以通过⼀些第三⽅⼯具)

任何⼀个能进⾏⽹络编程的语⾔都可以构造HTTP请求.本质上就是通过TCPsocket写⼊⼀个符合 HTTP协议规则的字符串.

其中,put 和 delete 往往是和get 和 post 搭配使用的

当遇到“Restful”风格的API设计,即你写一个HTTP服务器,给别人调用,你的服务器能支持哪些HTTP请求,并返回哪些HTTP响应,称为“HTTP的API”,而Restful是当前比较流行的HTTP API风格,不同的操作,通过不同的方法,明确语义。其中关于增删查改的约定就有:1,使用GET 实现查询 2,使用POST实现新增 3,使用PUT实现修改 4,使用DELETE实现删除

四,请求"报头"(header)

header 的整体的格式也是"键值对"结构

每个键值对占一行,键和值之间使用分号分割

4.1 Host

Host表示服务器主机的地址和端口。描述了要访问的服务器的IP(域名)和端口号

而这两个信息在URL里面也已经有了,后续服务器收到数据,可以针对HOST进行校验,以确认这个请求是不是我这个服务器要收的请求

--------------------

4.2 Content-Length

表示body中的数据长度,单位是字节

4.3 Content-Type

表示请求的body中的数据格式

浏览器/服务器会根据,这里填写的两个内容理解body

HTTP需要解决粘包问题

如果确实数据格式有误,浏览器/服务器试着“猜一下”,猜一下body到哪里结束

1)tcp连接关闭了,关闭前的数据就是一个HTTP数据包

2)tcp连接没有关闭,紧接着收到了形如“GET xxxxxxxxxxxHTTP/1.1....”这样的,就会认为之前的是一个HTTP数据包

4.3.1 常见选项

1)application/x-www-form-urlencoded : form 表单提交的数据格式.

此时body的格式形如:title=test&content=hello

2)multipart/form-data :form 表单提交的数据格式(在form标签中加上 enctyped="multipart/form-data" .通常用于提交图片/文件

body格式形如:

------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="username" zhangsan ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="age" 22 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="avatar"; filename="head.jpg" Content-Type: image/jpeg <这里是图片二进制字节流,原始文件内容> ------WebKitFormBoundary7MA4YWxkTrZu0gW--

3)application/json : 数据为json格式

body格式形如:

{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16}

小结:

请求中的Countent - Type(给服务器看的)

1)application/x-www-form-urlencoded

2)multipart/form-data

3)application/json

响应中的Countent-Type(给浏览器看的)

1)text/html

2)text/css

3)application/JavaScript

4)application/json

5)image/png

4.4 User-Agent (简称UA)

描述用户使用什么样的设备上网

表示浏览器/操作系统的属性,形如:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)

其中,Windows NT 10.0; Win64; x64 表示操作系统版本,AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 表示浏览器信息.(其中AppleWebKit为浏览器内核,Chrome/91.0.4472.77为浏览器版本,为苹果系统自带的浏览器)

4.5 Referer

表示这个页面是从哪个页面跳转过来的。

如果直接在浏览器中输入URL,或者直接通过收藏夹访问页面时是没有Referer的

referer可以帮助我们追踪请求的来源

4.6 Cookie

Cookie 中存储了⼀个字符串,这个数据可能是客户端(网页)自行通过JS写入的,也可能来自于服务器 (服务器在HTTP响应的header中通过Set-Cookie字段给浏览器返回数据).

往往可以通过这个字段实现"身份标识"的功能.

cookie中的值,也是键值对

cookie本质上是浏览器存储本地数据的一种机制

比如:浏览器打开一个网站,都是现场的从服务器获取代码,再执行的

一个网页本身是无法进行本地存储的(网页不能直接访问硬盘,如果可以访问硬盘就太危险了)

就像很多网站会有夜间模式等等,像这样当前页面是哪种模式的这种信息,保存在浏览器本地就好了,没必要从服务器获取,所以浏览器就开了个口子,虽然不能直接访问硬盘,但是允许按照键值对的格式来存储数据,不光是按照键值对存储的,还按照不同的网站涉及到的键值对分别分开存储了

小结

1)cookie 是干什么的?

浏览器本地存储数据的机制

2)cookie从哪里来?

服务器返回响应的时候,通过响应报头,写回到浏览器的

服务器的响应中,带有特殊的header,Set-Cookie(种Cookie)

每个Set-Cookie对应一个键值对,允许有多组

3)cookie要到哪里去?

本地存储不是目的,真正的目的是后续要发回给服务器

本地存储了cookie之后,接下来给服务器发的请求中,,都会在header里带上cookie内容

cookie中的键值对数据来自于服务器,又要发回给服务器不是多此一举,因为服务器会给很多个客户端提供服务

cookie典型应用场景 - 登录

使用cookie完成用户身份信息存储

比如:当前登录一个网站,一旦登录完成,后续访问这个网站的各个子页面,都能够获取到我们的登录状态,这也是基于cookie机制来实现的

1)最初注册的时候,设置的密码会按照加密的形式保存再数据库中。在查询数据库的时候,会拿着传输的密码加密后的效果和数据库里面的密码进行对比看是否正确

2)Session的保存,也是键值对结构

一个服务器可以同时有多个session,每个客户端都对应一个。服务器给每个session分配一个唯一的sessionId作为key,每个session分配一个session对象,作为value

(服务器内存中有一个hash表,存储了所有的会话数据)

一次会话(session)的多次交互可以是通过一个tcp连接完成的,也可以是多个

五,HTTP响应

5.1 状态码

状态码用于告诉客户端,请求是成功还是失败

更重要的是可以告诉失败的原因

状态码表示访问⼀个页面的结果.(是访问成功,还是失败,还是其他的⼀些情况...)

以下为常见的状态码:

200 OK

这是⼀个最常见的状态码,表示访问成功

404 NotFound

404 NotFound 表示没有找到资源

404一般是客户端的问题,代表客户端发来的url中的资源不对

403 Forbidden

表示访问被拒绝,有的页面通常需要用户具有⼀定的权限才能访问(登陆后才能访问)。如果用户没有登陆直接访问,就容易见到403

405 MethodNot Allowed

HTTP中所支持的方法,有GET,POST,PUT,DELETE等。但是对方的服务器不⼀定都支持所有的方法(或者不允许用户使用⼀些其他的方法).

500 Internal Server Error

服务器出现内部错误,⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这个状态码。咱们平时常⽤的⽹站很少会出现500(但是偶尔也能看到)

504 Gateway Timeout

当服务器负载⽐较⼤的时候,服务器处理单条请求的时候消耗的时间就会很⻓,就可能会导致出现超时的情况.

302 Movetemporarily(302 Found)

临时重定向

理解"重定向"

就相当于⼿机号码中的"呼叫转移"功能.

⽐如我本来的⼿机号是186-1234-5678,后来换了个新号码135-1234-5678,那么不需要让我的朋友知 道新号码, 只要我去办理⼀个呼叫转移业务,其他⼈拨打186-1234-5678,就会⾃动转移到135-1234-5678上.

在登陆页面中经常会见到302,用于实现登陆成功后自动跳转到主页

响应报文的header部分会包含⼀个Location字段,表示要跳转到哪个页面

以码云为例:

301 MovedPermanently

永久重定向,当浏览器收到这种响应时,后续的请求都会被自动改成新的地址

301 也是通过Location字段来表示要重定向到的新地址

301和302会影响到浏览器的缓存,如果是用301重定向,浏览器就会记住旧域名和新域名的对应关系,如果使用302,就不能缓存对应关系

418 状态码

定义HTTP标准协议的时候,加入了418这个彩蛋,没有任何意义

状态码小结

5.2 响应报头

响应报头的基本格式和请求报头的格式基本⼀致

类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义⼀致

Content-Type

1)text/html body数据格式是HTML

2)text/css body数据格式是CSS

3)application/JavaScript body数据格式是JavaScript

4)application/json body数据格式是JSON

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询