HTTP 协议
# 1. HTTP 协议介绍
基本介绍:
HTTP(Hyper Text Transfer Protocol): 全称为超文本传输协议,是用于在万维网(WWW)上从服务器传输超文本数据到客户端浏览器的应用层协议。
通信基础: HTTP 基于 TCP/IP 通信协议来传递数据。早期的 HTTP1.0 和 HTTP1.1 均使用 TCP 实现,HTTP2.0 对此进行了优化,仍基于 TCP,而最新的 HTTP3.0 基于 UDP 实现,以提高传输效率和安全性。目前主流使用 HTTP1.1 和 HTTP3.0。
协议概念: 网络通信中的协议是一组规定通信双方必须遵循的规则,确保数据能够在网络中从源头正确传递到目的地。HTTP 协议就是这样一组用于传输超文本数据的规则。
通俗解释: 协议就像是一种约定好的规则或“暗号”,只有遵守这个规则,双方才能正确理解和处理对方传递的信息。
注意: 在浏览网页时,常见的 HTTPS 是基于 HTTP 协议的一种安全增强版,它通过加密技术来确保通信的安全性和数据的完整性。HTTPS 的详细内容将在本文的后续部分介绍。
# 2. HTTP 协议的工作过程
当用户在浏览器中输入一个网址时,浏览器会向对应的服务器发送一个 HTTP 请求。服务器处理这个请求后,会返回一个 HTTP 响应,浏览器再根据响应内容呈现网页。在这个过程中,可能涉及多次 HTTP 请求和响应的交互。
基础术语:
- 客户端: 主动发起请求的一端(如浏览器)。
- 服务器: 被动接收请求并做出响应的一端(如网站服务器)。
- 请求: 客户端向服务器发送的消息。
- 响应: 服务器返回给客户端的消息。
HTTP 协议的重要特点: 每次请求都会对应一次响应,形成“一问一答”的通信模式。
注意: 除了一问一答的模式,网络通信中还有其他形式的通信模式,例如:
- 多发一收: 如上传大文件时,文件可能被分成多个部分发送给服务器。
- 一发多收: 如看直播时,客户端发送请求后,可能会接收到来自多个视频源的响应。
- 多发多收: 如实时数据串流(例如游戏中的视频串流)。
# 3. Fiddler 抓包工具介绍
# 3.1 抓包工具的使用
为了了解在浏览器访问网页时,HTTP 请求和响应是如何交互的,可以使用以下两种方式查看 HTTP 通信过程:
方式一: 使用浏览器开发者工具(按 F12 打开),在 Network 标签页下,刷新页面即可看到每个 HTTP 请求的记录。
示例:访问搜狗浏览器,使用开发者工具查看 HTTP 请求
方式二(推荐): 使用抓包工具,如 Fiddler,它可以直接读取电脑网卡的数据流,实时显示 HTTP 请求和响应。
Fiddler 下载地址: Fiddler 官网 (opens new window)
Fiddler 的使用方法:
- 打开 Fiddler,接着访问你要查看的网站,Fiddler 将会捕获并显示该网站的 HTTP 请求和响应。
示例:使用 Fiddler 抓取搜狗浏览器的 HTTP 请求
在 Fiddler 中选中一个具体的 HTTP 请求,可以在右上角看到该请求的报文内容,右下角显示响应报文内容(点击 Raw 标签查看详细数据格式)。
响应内容可以通过右下角的
view in Notepad
按钮打开,使用记事本查看详细内容。如果需要清除无关的抓包结果,可以按
Ctrl + A
全选,按Ctrl + X
删除,然后重新刷新页面进行抓包。在查看响应正文时,如果数据被压缩传输(如 GZIP 压缩),需要解压缩才能查看内容。
注意: 默认安装的 Fiddler 无法抓取 HTTPS 请求,需要进行额外配置。
# 3.2 抓包结果分析
以下是使用 Fiddler 抓取搜狗首页的 HTTP 请求和响应的结果:
完整的 HTTP 请求:
完整的 HTTP 响应:
# 3.3 抓包工具的原理
Fiddler 能够抓取 HTTP 请求和响应的详细信息,是因为它充当了一个“代理”程序。
代理就像一个中介,用户把需求告诉中介,中介会去寻找合适的资源,然后将找到的结果反馈给用户。
在使用 Fiddler 抓取搜狗首页的 HTTP 请求时,用户向 sogo.com 发送 HTTP 请求,Fiddler 作为代理接收该请求,然后转发给搜狗服务器。服务器返回响应后,Fiddler 先接收到响应内容,再将其返回给用户的浏览器。
# 4. HTTP 协议格式总览
通过抓包工具了解了 HTTP 请求和响应的交互过程后,接下来我们详细介绍 HTTP 协议的格式。
以下是以抓取搜狗首页请求为例,总览 HTTP 协议格式:
HTTP 请求格式:
HTTP 响应格式:
注意: HTTP 报文中存在的空行是非常重要的,它起到了结束标记或分隔符的作用。
- HTTP 协议中未规定报头的键值对数量,通过空行来标记报文的结束或报文与正文之间的分隔。
- HTTP 传输基于 TCP 协议,而 TCP 是面向字节流的。如果没有空行标记,可能会出现“粘包问题”。
# 5. HTTP 请求(Request)
# 5.1 认识 URL
基本介绍:
- URL(Uniform Resource Locator): 即统一资源定位符,是指向互联网上某个资源的地址,俗称“网址”。每个 URL 唯一对应一个互联网资源,包含了资源的位置及浏览器应如何处理该资源的信息。
# URL 基本格式
标准格式:
协议类型:[//服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
1完整格式:
协议类型:[//[访问资源需要的凭证信息@]服务器地址[:端口号]][/资源层级 UNIX 文件路径]文件名[?查询字符串][#片段标识符]
1
# URL 参数介绍
参数 | 描述 | 可否省略 |
---|---|---|
协议类型 | 协议类型,常见为 HTTP 和 HTTPS,访问数据库时可为 jdbc:mysql 。 | 可以省略,省略后默认为 http:// 。 |
访问资源需要的凭证信息 | 登录信息如用户名和密码,用于某些资源访问认证。现代网站一般不再使用 URL 传递凭证,因此常省略。 | 可以省略 |
服务器地址 | 服务器地址可为 IP 地址或域名,域名通过 DNS 系统解析为 IP 地址。 | 可以省略,在 HTML 中省略则默认与当前 HTML 所属的 IP 或域名一致。 |
端口号 | 标识特定进程提供的服务,HTTP 默认端口为 80,HTTPS 为 443。 | 可以省略,浏览器会根据协议类型自动使用默认端口号。 |
资源层级 UNIX 文件路径 | 服务器上资源的路径。 | 可以省略,省略后相当于 / 。 |
文件名 | 服务器上资源的名称,如 HTML 文件或图片等。 | 不能省略 |
查询字符串 | 查询字符串是键值对形式的参数,用于客户端向服务器传递信息。 | 可以省略 |
片段标识符 | 用于页面内跳转,例如跳转到页面的某一部分或章节。 | 可以省略 |
URL 实例分析:
CSDN 博客首页:
https://blog.csdn.net/m0_53882348?type=lately
1搜狗首页:
https://www.sogou.com/
1QQ 邮箱首页:
https://mail.qq.com/cgi-bin/frame_html? sid=jXYSnAPw1gkphz9d&r=11a219ff7f0405c621f10f04a0cfb41d
1
我们会发现,上述几个 URL 都并不完整,因为 URL 中的有些参数是可以省略的。
# URLencode介绍
当用户在网页中输入中文或特殊字符(如空格)进行搜索时,这些字符会被编码为 URLencode 形式,以确保浏览器能正确传输和解析这些字符。
例如,在搜狗搜索“蛋糕”时,URL 中的中文“蛋糕”会被编码为 %E8%9B%8B%E7%B3%95
。
- URLencode: 将 URL 中的中文、空格等字符转换为 16 进制编码。
- URldecode: 将 URL 中的 16 进制编码转换为原始字符。
需要URLencode 原因:
- 特殊字符(如
/
、?
、:
等)在 URL 中有特殊含义,若这些字符作为数据传输时,必须先进行转义,即 URLencode。 - 中文字符在 URL 中不能直接使用,需编码为 16 进制后再进行传输。
转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成
%XY
格式。但是现在网上有很多现成的可以进行转码的工具,因此需要的时候找度娘即可!
常见字符的转码示例:
原始字符 | 转码后 URLencode 表示 |
---|---|
空格 | %20 |
# | %23 |
% | %25 |
& | %26 |
+ | %2B |
/ | %2F |
: | %3A |
; | %3B |
= | %3D |
# 5.2 认识 HTTP 方法(Method)
基本介绍:
HTTP 方法即请求报文中首行的第一个字段,用于指定请求类型。原本设计中,不同的方法用于表达不同的语义,但实际应用中,多数场景只常用 GET 和 POST 方法。
方法 | 说明 | 适用版本号 |
---|---|---|
GET | 获取资源 | HTTP 1.0、HTTP 1.1 |
POST | 传输实体主体 | HTTP 1.0、HTTP 1.1 |
PUT | 传输文件 | HTTP 1.0、HTTP 1.1 |
HEAD | 获得报文首部 | HTTP 1.0、HTTP 1.1 |
DELETE | 删除文件 | HTTP 1.0、HTTP 1.1 |
OPTIONS | 访问支持的方法 | HTTP 1.1 |
TRACE | 追踪路径 | HTTP 1.1 |
CONNECT | 用隧道协议连接代理 | HTTP 1.1 |
LINK | 建立与资源的联系 | HTTP 1.1 |
UNLINK | 断开与资源的联系 | HTTP 1.1 |
# GET 方法
GET 是最常用的 HTTP 方法,常用于获取服务器上的某个资源。以下几种方式都会触发 GET 方法的请求
- 在浏览器中直接输入 URL 回车或点击浏览器收藏夹中的链接,此时浏览器就会发送出一个 GET 请求。
- HTML 中的 link、img、script 等标签的属性中放的 URL,浏览器也会构造出 HTTP GET 请求
- 使用 Javascript 重点 ajax,也能构造出 HTTP GET 请求
- 各种编程语言(只要能够访问网络),就都能够构造出 HTTP GER 请求
GET 请求的特点:
- URL 包含 query string,首行第一个字段为 GET。
- 请求头(header)含有若干键值对结构。
- 请求体(body)通常为空。
GET 请求示例: 如下图所示为搜狗首页的 GET 请求。
# POST 方法
POST 方法也是一种常见的方法,多用于提交用户输入的数据给服务器(如登录页面)。以下几种方法都会触发 POST 方法的请求
- 通过 HTML 中的 form 标签可以构造 POST 请求
- 使用 JavaScript 的 ajax 可以构造 POST 请求
POST 请求的特点:
- URL 中 query string 为空,首行第一个字段为 POST。
- 请求头(header)中包含键值对结构。
- 请求体(body)包含数据,具体格式由 header 中的
Content-Type
描述,长度由Content-Length
描述。
POST 请求示例: 如下图所示为 QQ 邮箱的 POST 请求。
# GET 和 POST 的区别
GET 和 POST 没有本质区别,但在使用上有一些不同:
- GET: 习惯用于从服务器获取数据,参数通常放在 URL 的 query string 中。
- POST: 习惯用于向服务器提交数据,参数通常放在请求体中。
- 幂等性: 一般来说,GET 请求应实现为幂等的,POST 请求则不要求幂等性。
- 缓存和收藏: GET 请求可以被缓存并保存为浏览器收藏夹,POST 请求则不能。
幂等性:
幂等性是指同样的请求执行一次与执行多次的效果是一样的,服务器状态也一致。GET、HEAD、PUT 和 DELETE 方法通常是幂等的,而 POST 方法则不一定。
# 关于 GET 请求的 URL 长度问题的误解
- 网上有一种错误的解释: GET 请求的长度是存在上限的,这个上限有被说成 1024kb、2048kb 等等,并且 GET 请求存在上限的原因是 URL 的长度存在上限
- RFC 2616 标准正确的解释: HTTP 协议由 RFC 2616 标准定义,该标准中明确说明
"Hypertext Transfer Protocol -- HTTP/1.1," does not specify any requirement for URL length
,即没有对 URL 的长度有任何限制 - URL 的长度取决因素: 实际上 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现。在浏览器端,不同的浏览器最大的长度是不同的,但是现在浏览器支持的长度一般都很长;在服务器端,一般这个长度是可以配置的
# 关于 POST 比 GET 更安全的误解
- 网上有一种错误的解释: 如果实现登录页面,如果使用 GET 实现登录,GET 习惯上把数据放到 query string 中,此时就能看到浏览器的 URL 中显示当前的用户名和密码了,所以就并不安全;而 POST 习惯上会把数据放到 body 中,因此登录时就不能直接看到用户名和密码,就安全
- 正确的理解: 安全问题取决于是否加密以及加密算法的强度。这和将数据信息放到 query string 或 body 中无关,因为通过抓包,我们就可以得到这两部分的数据
# 关于 GET 只能传输文本数据的误解
- 网上有一种错误的解释: GET 只能传输文本数据;POST 可以传输文本数据,也可以传输二进制数据
- 正确的理解: GET 也可以传输二进制数据,虽然不能直接在 query string 中传输二进制数据,但是可以针对二进制数据进行 urlencode,转码后就可以放到 url 中;GET 还可以直接将二进制数据放到 body 中
其他方法:
- PUT: 类似于 POST,但具有幂等性,用于更新资源。
- DELETE: 删除服务器上的指定资源。
- OPTIONS: 返回服务器支持的请求方法。
- HEAD: 类似于 GET,但不返回响应体。
- TRACE: 显示服务器收到的请求路径,通常用于调试。
- CONNECT: 预留方法,用于未来的协议拓展。
# 5.3 认识请求“报头”(header)
HTTP 请求报头(header)是请求消息的头部信息部分,用于传递关于客户端环境、请求体内容、请求身份验证等的元数据。报头的格式是键值对结构,每个键值对占一行,键和值之间使用 冒号 + 空格
进行分割。
# 1. Host
说明:
Host
报头字段指定了服务器的主机地址和端口号。服务器地址可以是域名或 IP 地址,端口号可以省略(当省略时,默认使用 HTTP 的 80 端口或 HTTPS 的 443 端口)。示例:
Host: www.example.com
1作用:当一个服务器主机上运行多个网站时,
Host
报头帮助服务器区分客户端要访问的具体站点。
# 2. Content-Length
说明:
Content-Length
报头字段指定了请求体的字节长度。它用于指示请求消息的大小。示例:
Content-Length: 348
1作用:服务器根据
Content-Length
知道请求体的长度,从而正确读取请求内容。
# 3. Content-Type
说明:
Content-Type
报头字段指定了请求体的媒体类型(MIME type),即服务器处理请求体的方式。常见的数据格式包括application/x-www-form-urlencoded
、multipart/form-data
、application/json
等。常见取值:
application/x-www-form-urlencoded
:适用于表单数据,数据格式类似于 URL 中的查询字符串(键值对形式)。multipart/form-data
:用于上传文件时,表单数据的编码方式。需在<form>
标签中指定enctype="multipart/form-data"
。application/json
:适用于传输 JSON 格式的数据。通常用于 API 请求中,数据以 JSON 对象的格式传递。
示例:
Content-Type: application/json
1作用:服务器根据
Content-Type
解析请求体内容,决定如何处理数据。
# 4. User-Agent
说明:
User-Agent
报头字段标识客户端使用的浏览器或操作系统信息。这是一个字符串,通常包含浏览器名称、版本号、操作系统及其版本信息。示例:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36
1作用:服务器可以通过
User-Agent
了解客户端的环境,从而针对不同的浏览器或设备进行兼容性调整或内容定制。
# 5. Referer
说明:
Referer
报头字段用于表示请求来源的页面 URL,即当前请求是从哪个页面跳转过来的。示例:
Referer: https://www.bing.com/search?q=cake
1作用:
Referer
常用于分析用户行为,统计广告点击率,跟踪用户来源等。在广告链接中,Referer
可以帮助广告主统计广告在某个页面的点击次数。注意:如果用户直接在浏览器地址栏中输入 URL 或通过书签访问页面,
Referer
通常为空。
# 6. Cookie
说明:
Cookie
报头字段用于在客户端和服务器之间传递少量数据,通常用于身份验证、会话跟踪等。Cookie
的内容是键值对结构,多个键值对之间用;
分隔。示例:
Cookie: sessionId=abc123; username=JohnDoe
1作用:
Cookie
常用于维持用户的登录状态。例如,当用户在网站上登录时,服务器生成一个唯一的会话 ID 并将其存储在Cookie
中。随后每次请求中,浏览器都会将该Cookie
发送回服务器,从而识别用户身份并维持会话。注意:
Cookie
由服务器通过 HTTP 响应中的Set-Cookie
字段设置,存储在客户端,并在后续请求中自动附带到请求头中。
# 7. 自定义报头字段
HTTP 报头可以自定义吗?
是的,HTTP 允许自定义报头字段。自定义报头字段通常用于传递特定的应用级别的元数据,或者在客户端和服务器之间传递额外的身份验证信息、追踪信息等。
自定义报头字段的命名推荐以
X-
前缀开头,以区别于标准的 HTTP 报头字段。尽管以X-
前缀开头已不是强制性要求,但依然是一种良好的实践。示例:
X-Custom-Token: abcdef12345
1自定义报头可以用于不同的目的,例如:
- 在请求中传递自定义的认证信息。
- 在应用之间传递特定的上下文信息。
- 用于调试或跟踪请求信息。
# 8. 前端自定义请求报头的语法
在前端开发中,通过 XMLHttpRequest
或 fetch
API,可以很方便地自定义 HTTP 请求报头。以下是如何自定义报头的示例。
使用 XMLHttpRequest 自定义报头:
const xhr = new XMLHttpRequest(); xhr.open('GET', '/api/data', true); xhr.setRequestHeader('X-Custom-Token', 'abcdef12345'); // 自定义报头 xhr.send();
1
2
3
4使用 Fetch API 自定义报头:
fetch('/api/data', { method: 'GET', headers: { 'X-Custom-Token': 'abcdef12345', // 自定义报头 'Content-Type': 'application/json' } }) .then(response => response.json()) .then(data => console.log(data));
1
2
3
4
5
6
7
8
9使用 Axios 自定义报头:
axios.get('/api/data', { headers: { 'X-Custom-Token': 'abcdef12345', // 自定义报头 'Content-Type': 'application/json' } }) .then(response => console.log(response.data)) .catch(error => console.error(error));
1
2
3
4
5
6
7
8
注意事项
- 并非所有的自定义报头都会被浏览器允许发送。某些敏感的报头,如
Host
和Content-Length
,是由浏览器自动设置的,开发者无法手动更改。 - 自定义报头可能受到 CORS(跨域资源共享)的限制。服务器需要在响应的
Access-Control-Allow-Headers
报头中明确允许这些自定义的报头字段,客户端才能发送这些报头。
# 6. HTTP 响应(Response)
# 6.1 认识“状态码”(status code)
类别 | 原因 | |
---|---|---|
1xx | Informational(信息性状态码) | 接收的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理完毕 |
3xx | Redirection(重定向状态码) | 需要进行附加操作完成请求 |
4xx | Client Error(客户端错误状态码) | 服务器无法完成请求 |
5xx | Server Error(服务器错误状态码) | 服务器处理请求出错 |
HTTP状态码,即HTTP协议状态码,是我们访问网站时会遇到的,服务器端返回的Http响应码,不同的数字分别代表着不同的响应状态。我们在做SEO或做网页开发过程中需要了解5类比较重要的HTTP状态码,可以根据请求响应代码检查服务器及程序是否正常,判断网页处于什么工作状态。我们就需要了解不同的状态码分别是什么含义。
下面我们列出常见五类HTTP状态码和它的详解说明:
# 1xx 请求信息
这一组状态码表明这是一个临时性响应。此响应仅由状态行和可选的HTTP头组成,以一个空行结尾。由于HTTP/1.0未定义任何1xx状态码,所以不要向HTTP/1.0客户端发送1xx响应。
Http状态码 | Http Status Code | Http状态码含义中文说明 |
---|---|---|
100 | 100 Continue (opens new window) | 请继续请求 |
101 | 101 Switching Protocols (opens new window) | 请切换协议 |
102 | 102 Processing (opens new window) | 将继续执行请求 |
# 2xx 成功状态
这一组状态码表明客户端的请求已经被服务器端成功接收并正确解析。
Http状态码 | Http Status Code | Http状态码含义中文说明 |
---|---|---|
200 | 200 OK (opens new window) | 请求成功 |
201 | 201 Created (opens new window) | 请求已被接受,等待资源响应 |
202 | 202 Accepted (opens new window) | 请求已被接受,但尚未处理 |
203 | 203 Non-Authoritative Information (opens new window) | 请求已成功处理,结果来自第三方拷贝 |
204 | 204 No Content (opens new window) | 请求已成功处理,但无返回内容 |
205 | 205 Reset Content (opens new window) | 请求已成功处理,但需重置内容 |
206 | 206 Partial Content (opens new window) | 请求已成功处理,但仅返回了部分内容 |
207 | 207 Multi-Status (opens new window) | 请求已成功处理,返回了多个状态的XML消息 |
208 | 208 Already Reported (opens new window) | 响应已发送 |
226 | 226 IM Used (opens new window) | 已完成响应 |
# 3xx 重定向状态
这一组状态码表示客户端需要采取更进一步的行动来完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。
Http状态码 | Http Status Code | Http状态码含义中文说明 |
---|---|---|
300 | 300 Multiple Choices (opens new window) | 返回多条重定向供选择 |
301 | 301 Moved Permanently (opens new window) | 永久重定向 |
302 | 302 Found (opens new window) | 临时重定向 |
303 | 303 See Other (opens new window) | 当前请求的资源在其它地址 |
304 | 304 Not Modified (opens new window) | 请求资源与本地缓存相同,未修改 |
305 | 305 Use Proxy (opens new window) | 必须通过代理访问 |
306 | 306 (已废弃)Switch Proxy (opens new window) | (已废弃)请切换代理 |
307 | 307 Temporary Redirect (opens new window) | 临时重定向,同302 |
308 | 308 Permanent Redirect (opens new window) | 永久重定向,且禁止改变http方法 |
# 4xx 客户端错误
这一组状态码表示客户端的请求存在错误,导致服务器无法处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
# 5xx 服务器错误状态
这一组状态码说明服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。
Http状态码 | Http Status Code | Http状态码含义中文说明 |
---|---|---|
500 | 500 Internal Server Error (opens new window) | 服务器端程序错误 |
501 | 501 Not Implemented (opens new window) | 服务器不支持的请求方法 |
502 | 502 Bad Gateway (opens new window) | 网关无响应 |
503 | 503 Service Unavailable (opens new window) | 服务器端临时错误 |
504 | 504 Gateway Timeout (opens new window) | 网关超时 |
505 | 505 HTTP Version Not Supported (opens new window) | 服务器不支持的HTTP版本 |
506 | 506 Variant Also Negotiates (opens new window) | 服务器内部配置错误 |
507 | 507 Insufficient Storage (opens new window) | 服务器无法存储请求 |
508 | 508 Loop Detected (opens new window) | 服务器因死循环而终止操作 |
509 | 509 Bandwidth Limit Exceeded (opens new window) | 服务器带宽限制 |
510 | 510 Not Extended (opens new window) | 获取资源策略未被满足 |
511 | 511 Network Authentication Required (opens new window) | 需验证以许可连接 |
599 | 599 Network Connect Timeout Error (opens new window) | 网络连接超时 |
# 6.2 认识响应“报头”(Response Headers)
响应报头包含服务器返回给客户端的元数据,用于描述响应体的类型、长度、编码等信息。
# 常见的响应报头字段
Content-Type
说明:指定响应体的数据类型,通常是 MIME 类型,用于告诉客户端如何处理返回的数据。
常见值:
text/html
:HTML 格式的数据。text/css
:CSS 样式表。application/javascript
:JavaScript 文件。application/json
:JSON 格式的数据。image/jpeg
、image/png
:图片文件。
示例:
Content-Type: application/json
1Content-Length
说明:指定响应体的字节长度,帮助客户端确定内容长度,用于管理内容的传输。
示例:
Content-Length: 348
1Set-Cookie
说明:用于设置客户端 Cookie,服务器通过此字段将数据写入客户端浏览器的 Cookie 中,通常用于会话管理和身份验证。
示例:
Set-Cookie: sessionId=abc123; Path=/; HttpOnly
1Cache-Control
说明:指定缓存机制的指令,用于控制客户端和中间缓存服务器如何缓存响应数据。
常见值:
no-cache
:不缓存。private
:仅客户端可以缓存。public
:可以被客户端和代理服务器缓存。
示例:
Cache-Control: no-cache
1Location
说明:在重定向响应中,
Location
字段指定客户端需要重新请求的 URL。通常与 3xx 状态码配合使用。示例:
Location: https://www.example.com/newpage
1Server
说明:指定处理请求的服务器软件信息,包括服务器名称、版本等。
示例:
Server: Apache/2.4.1 (Unix)
1
# 响应报头的格式
响应报头的格式与请求报头类似,是一个键值对的结构,每个键值对占一行。键和值之间使用 冒号+空格
进行分割。
Content-Type: text/html; charset=UTF-8
Content-Length: 138
Cache-Control: no-cache
2
3
# 6.3 状态行(Status Line)
状态行是响应的第一行,包含 HTTP 协议版本、状态码,以及状态码的简短描述。
状态行的格式:
HTTP-Version Status-Code Reason-Phrase
示例:
HTTP/1.1 200 OK
- HTTP-Version:协议版本,通常为
HTTP/1.1
或HTTP/2.0
。 - Status-Code:状态码,三位数字,用于标识响应结果。
- Reason-Phrase:状态码的简短描述,例如
OK
、Not Found
等。
# 7. 通过 form 表单构造 HTTP 请求
HTML 中的 <form>
标签用于创建提交表单,表单可以用来向服务器发送 HTTP 请求。通常情况下,表单会提交到服务器处理,如保存用户数据或执行某些操作。
# 7.1 form 标签的基本参数
- action:用于指定请求的 URL,即请求将发送到的服务器地址。
- method:指定请求的 HTTP 方法,通常是
GET
或POST
。
# 7.2 input 标签的基本参数
- type:指定输入框的类型,例如
text
表示文本输入框,password
表示密码输入框,submit
表示提交按钮等。 - name:表示输入字段的名称,将作为构造出的 HTTP 请求中
query string
的键(Key)。 - value:输入字段的值,将作为构造出的 HTTP 请求中
query string
的值(Value)。对于type="submit"
类型的按钮,value
代表按钮上显示的文本。 - 输入框的内容:表示输入的数据,将作为
query string
的值。
# 7.3 提交表单生成 HTTP 请求
当用户填写完表单并点击 submit
按钮后,表单中的数据将通过指定的 HTTP 方法(GET
或 POST
)提交到服务器。
# 7.4 发送 GET 请求
在表单中,使用 GET
方法时,表单中的数据将被编码为 URL 中的 query string
,并随 URL 一起发送到服务器。GET
请求的数据会直接附加在 URL 后面,这意味着所有的数据都会出现在浏览器的地址栏中。
示例代码:
<!-- 使用 GET 方法构造请求 -->
<form action="http://example.com/myPath" method="get">
<input type="text" name="username" placeholder="请输入用户名">
<input type="password" name="password" placeholder="请输入密码">
<input type="submit" value="提交">
</form>
2
3
4
5
6
分析:
- action:
http://example.com/myPath
是请求的目标 URL。 - method:
get
表示使用GET
方法提交表单。 - username 和 password:用户输入的值会作为 URL 的
query string
发送。
提交后的请求格式:
假设用户输入了 username=admin
和 password=123456
,则提交后生成的请求为:
GET http://example.com/myPath?username=admin&password=123456 HTTP/1.1
所有的表单数据都被附加到 URL 末尾。
GET 请求的特点:
- 数据暴露在 URL 中,可能会被浏览器记录,也容易被第三方看到。
GET
请求有 URL 长度限制,因此不适合提交大数据量的信息。
# 7.5 发送 POST 请求
在表单中使用 POST
方法时,表单中的数据不会直接显示在 URL 中,而是被编码为请求的主体内容(body)发送到服务器。POST
请求通常用于提交较大数据量或敏感数据,如登录表单、文件上传等。
示例代码:
<!-- 使用 POST 方法构造请求 -->
<form action="http://example.com/myPath" method="post">
<input type="text" name="username" placeholder="请输入用户名">
<input type="password" name="password" placeholder="请输入密码">
<input type="submit" value="提交">
</form>
2
3
4
5
6
分析:
- action:
http://example.com/myPath
是请求的目标 URL。 - method:
post
表示使用POST
方法提交表单。 - username 和 password:用户输入的值会作为请求体中的数据发送。
提交后的请求格式:
假设用户输入了 username=admin
和 password=123456
,则提交后生成的请求为:
POST http://example.com/myPath HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
username=admin&password=123456
2
3
4
5
表单数据被编码为 application/x-www-form-urlencoded
格式,并包含在请求体中。
POST 请求的特点:
- 数据不会显示在 URL 中,相对较为安全。
- 没有数据长度限制,适合提交大数据量的信息。
POST
请求通常用于操作数据,如创建资源、提交表单、上传文件等。
# 7.6 GET 与 POST 的比较
虽然 GET
和 POST
都可以用于发送表单数据,但它们在实际使用中有一些重要的区别:
- 数据传输方式:
GET
请求通过 URL 传输数据,而POST
请求通过请求体传输数据。 - 安全性:
POST
相对更安全,因为数据不直接暴露在 URL 中。 - 数据长度限制:
GET
请求受 URL 长度限制,POST
请求没有此限制。 - 使用场景:
GET
请求适合获取数据,如请求页面内容、获取资源等;POST
请求适合提交数据,如提交表单、上传文件等。
# 7.7 通过 form 表单提交其他数据格式
提交 JSON 格式数据
如果需要通过表单提交 JSON 格式的数据,可以通过 JavaScript 自行构造请求并提交:
<form id="myForm">
<input type="text" name="username" placeholder="请输入用户名">
<input type="password" name="password" placeholder="请输入密码">
<input type="button" value="提交" onclick="submitForm()">
</form>
<script>
function submitForm() {
const form = document.getElementById('myForm');
const formData = new FormData(form);
const json = JSON.stringify(Object.fromEntries(formData.entries()));
fetch('http://example.com/myPath', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: json
}).then(response => {
return response.json();
}).then(data => {
console.log(data);
}).catch(error => {
console.error('Error:', error);
});
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
分析:
- 使用
FormData
结合fetch
方法发送POST
请求,将表单数据转换为 JSON 格式,并通过fetch
的body
发送到服务器。
# 8. 通过 Ajax 构造 HTTP 请求
Ajax(Asynchronous JavaScript And XML) 是一种用于在无需重新加载整个网页的情况下,异步更新部分网页内容的技术。Ajax 通过在后台与服务器进行数据交换,可以实现动态网页更新。与传统的网页不同,Ajax 允许在不刷新整个页面的情况下更新其某部分内容。
在这个部分,我们将使用第三方库 jQuery 提供的简化版 Ajax 方法来构造 HTTP 请求。jQuery 对原生的 Ajax 方法进行了封装,使得操作更加简单和直观。
# 8.1 jQuery 和 CDN 的使用
CDN(内容分发网络) 是一种通过将内容分发到多个地理位置的服务器,从而加速访问的技术。通过使用 CDN 提供的 jQuery 链接,我们可以快速地加载 jQuery 库,而无需将其下载到本地。
如何使用 jQuery 的 CDN:
- 搜索 jQuery 的 CDN 地址,例如
https://code.jquery.com/jquery-3.6.0.min.js
。 - 将复制好的链接粘贴到 HTML 文件中的
<script>
标签中。
示例代码:
<!-- 引入 jQuery 库 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
2
引入 jQuery 后,我们就可以使用其提供的 $
对象来操作 DOM、发起 Ajax 请求等。
# 8.2 jQuery 中的重要参数
$
:这是 jQuery 的全局对象,所有 jQuery 的方法和属性都通过这个对象来访问。ajax
:这是 jQuery 提供的核心方法,用于发起 Ajax 请求。它接受一个配置对象,包含各种参数来定义请求的行为。url
:定义请求的目标地址,即要访问的 API 或服务器的 URL。method
:指定 HTTP 请求的方法,如GET
、POST
等。contentType
:定义请求发送的数据类型(Content-Type),如application/json
、text/plain
等。data
:请求体中的数据,通常在POST
请求中使用。status
:表示响应的状态码(如 200 表示成功)。success
:这是一个回调函数,当请求成功时会自动调用此函数,函数参数包括响应的数据和状态。
# 8.3 发送 GET 请求
使用 Ajax 发送 GET
请求可以从服务器获取数据。通常用于请求数据或加载页面部分内容。
示例代码:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
// 使用 jQuery 的 ajax 方法发送 GET 请求
$.ajax({
url: 'http://example.com/api/data', // 目标 URL
method: 'GET', // 使用 GET 方法
success: function(data, status) {
// 请求成功时执行的回调函数
console.log(data); // 输出服务器返回的数据
console.log(status); // 输出请求状态
}
});
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
代码说明:
url
:http://example.com/api/data
是请求的目标 API 地址。method
:使用GET
方法发起请求。success
:在请求成功后,服务器返回的数据会作为参数传递给这个函数并打印到控制台。
GET 请求的特点:
- 通过 URL 传递数据,数据会显示在浏览器的地址栏中。
- 适合用于请求数据或查询操作。
# 8.4 发送 POST 请求
使用 Ajax 发送 POST
请求通常用于提交数据到服务器,如表单数据、用户信息等。POST
请求不会将数据附加到 URL 上,而是将数据放在请求体中。
示例代码:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
// 使用 jQuery 的 ajax 方法发送 POST 请求
$.ajax({
url: 'http://example.com/api/submit', // 目标 URL
method: 'POST', // 使用 POST 方法
contentType: 'application/json', // 指定请求体的数据格式为 JSON
data: JSON.stringify({ name: 'John Doe', age: 30 }), // 将数据序列化为 JSON 格式
success: function(data, status) {
// 请求成功时执行的回调函数
console.log(data); // 输出服务器返回的数据
console.log(status); // 输出请求状态
}
});
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
代码说明:
url
:http://example.com/api/submit
是请求的目标 API 地址。method
:使用POST
方法发起请求。contentType
:指定请求体中的数据格式为application/json
。data
:请求体中的数据,这里使用JSON.stringify
方法将 JavaScript 对象序列化为 JSON 字符串。success
:在请求成功后,服务器返回的数据会作为参数传递给这个函数并打印到控制台。
POST 请求的特点:
- 数据通过请求体发送,不会显示在 URL 中。
- 适合用于提交表单、上传数据等操作。
# 8.5 其他 HTTP 请求方法
除了 GET
和 POST
之外,Ajax 还可以发起其他类型的 HTTP 请求,如 PUT
、DELETE
等。这些请求方法通常用于 RESTful API 的操作,例如更新数据、删除数据等。
发送 PUT 请求的示例:
$.ajax({
url: 'http://example.com/api/update/1', // 目标 URL
method: 'PUT', // 使用 PUT 方法
contentType: 'application/json', // 指定请求体的数据格式为 JSON
data: JSON.stringify({ name: 'Jane Doe', age: 25 }), // 将数据序列化为 JSON 格式
success: function(data, status) {
console.log('更新成功:', data);
}
});
2
3
4
5
6
7
8
9
发送 DELETE 请求的示例:
$.ajax({
url: 'http://example.com/api/delete/1', // 目标 URL
method: 'DELETE', // 使用 DELETE 方法
success: function(data, status) {
console.log('删除成功:', data);
}
});
2
3
4
5
6
7
# 8.6 跨域请求与限制
**注意:**由于同源策略的限制,Ajax 请求通常只能访问与当前页面相同域名的资源。跨域请求(访问不同域名的资源)需要服务器配置允许跨域访问(CORS)。
如何解决跨域问题:
- 服务器端配置 CORS:在服务器端配置响应头,允许跨域访问。例如,添加
Access-Control-Allow-Origin
响应头。 - JSONP:一种通过
<script>
标签加载远程资源的方式,通常用于解决早期的跨域问题。