Web请求
超文本传输协议 (HTTP)
URL结构
成分 | 例子 | 描述 |
---|---|---|
Scheme |
http:// https:// |
用于识别客户端正在访问的协议,以冒号和双斜杠 ( :// )结尾 |
User Info |
admin:password@ |
这是一个可选组件,包含用于向主机进行身份验证的凭据(以冒号分隔),并以 at 符号 ( ): 与主机分隔。@ |
Host |
inlanefreight.com |
主机表示资源位置。可以是主机名或 IP 地址 |
Port |
:80 |
Port 和Host 之间用冒号 ( )分隔: 。如果没有指定端口,http 则方案默认为端口80 ,https 默认为端口443 |
Path |
/dashboard.php |
指向正在访问的资源,可以是文件或文件夹。如果没有指定路径,服务器将返回默认索引(例如index.html )。 |
Query String |
?login=true |
查询字符串以问号 ( ? ) 开头,由一个参数(例如login )和一个值(例如true )组成。多个参数可以用与号 ( & ) 分隔。 |
Fragments |
#status |
客户端的浏览器会处理片段,以定位主要资源中的各个部分(例如页面上的标题或部分)。 |
HTTP 流
用户首次inlanefreight.com
在浏览器中输入 URL ( ) 时,它会向 DNS(域名系统)服务器发送请求,以解析域名并获取其 IP 地址。DNS 服务器查找 IP 地址inlanefreight.com
并返回。所有域名都需要以这种方式解析,因为服务器没有 IP 地址就无法通信。
[!NOTE]
注意:我们的浏览器通常会先在本地“ ”文件中查找记录
/etc/hosts
,如果请求的域名不存在,则会联系其他 DNS 服务器。我们可以使用“/etc/hosts
”手动添加记录进行 DNS 解析,方法是先添加 IP 地址,再添加域名。
HTTP 请求
场地 | 例子 | 描述 |
---|---|---|
Method |
GET |
HTTP 方法或动词,指定要执行的操作类型。 |
Path |
/users/login.html |
所访问资源的路径。此字段也可以以查询字符串作为后缀(例如?username=user )。 |
Version |
HTTP/1.1 |
第三个也是最后一个字段用于表示 HTTP 版本。 |
接下来的几行包含 HTTP 标头值对,例如Host
、User-Agent
、Cookie
以及许多其他可能的标头。这些标头用于指定请求的各种属性。标头以换行符结尾,这是服务器验证请求所必需的。最后,请求可能以请求正文和数据结尾。
[!NOTE]
注意: HTTP 1.X 版本以明文形式发送请求,并使用换行符分隔不同的字段和不同的请求。而 HTTP 2.X 版本则以字典形式的二进制数据发送请求。
HTTP 响应
HTTP 响应的第一行包含两个以空格分隔的字段。第一个字段表示HTTP version
(eg HTTP/1.1
),第二个字段表示HTTP response code
(eg 200 OK
)。
最后,响应可能以响应主体结尾,主体在标头后以换行符分隔。响应主体通常定义为HTML
代码。但是,它也可以响应其他类型的代码
HTTP 标头
通用标题
标题 | 例子 | 描述 |
---|---|---|
Date |
Date: Wed, 16 Feb 2022 10:38:44 GMT |
保存消息发出的日期和时间。建议将时间转换为标准UTC时区。 |
Connection |
Connection: close |
指示请求完成后当前网络连接是否应保持活动状态。此标头的两个常用值是close 和keep-alive 。close 来自客户端或服务器的值表示它们希望终止连接,而keep-alive 标头则指示连接应保持打开状态以接收更多数据和输入。 |
实体标头
标题 | 例子 | 描述 |
---|---|---|
Content-Type |
Content-Type: text/html |
用于描述正在传输的资源类型。该值由客户端浏览器自动添加,并在服务器响应中返回。该charset 字段表示编码标准,例如UTF-8。 |
Media-Type |
Media-Type: application/pdf |
类似于media-type ,Content-Type 用于描述正在传输的数据。此标头在服务器解释我们的输入时起着至关重要的作用。charset 字段也可以与此标头一起使用。 |
Boundary |
boundary="b4e4fbd93540" |
当同一条消息中包含多个内容时,此边界可用作分隔内容的标记。例如,在表单数据中,此边界用于--b4e4fbd93540 分隔表单的不同部分。 |
Content-Length |
Content-Length: 385 |
保存正在传递的实体的大小。此标头是必需的,因为服务器使用它来从消息正文中读取数据,并且由浏览器和 cURL 等工具自动生成。 |
Content-Encoding |
Content-Encoding: gzip |
数据在传递之前可能会经过多种转换。例如,可以压缩大量数据以减小消息大小。所使用的编码类型应在Content-Encoding 标头中指定。 |
请求标头
标题 | 例子 | 描述 |
---|---|---|
Host |
Host: www.inlanefreight.com |
用于指定查询资源的主机。可以是域名或 IP 地址。HTTP 服务器可以配置为托管不同的网站,这些网站会根据主机名显示。这使得主机头成为一个重要的枚举目标,因为它可以指示目标服务器上是否存在其他主机。 |
User-Agent |
User-Agent: curl/7.77.0 |
标User-Agent 头用于描述请求资源的客户端。此标头可以揭示很多有关客户端的信息,例如浏览器、浏览器版本以及操作系统。 |
Referer |
Referer: http://www.inlanefreight.com/ |
指示当前请求的来源。例如,点击 Google 搜索结果中的链接将生成https://google.com referer。信任此标头可能很危险,因为它很容易被操纵,从而导致意想不到的后果。 |
Accept |
Accept: */* |
标Accept 头描述了客户端可以理解的媒体类型。它可以包含多个媒体类型,并以逗号分隔。该*/* 值表示接受所有媒体类型。 |
Cookie |
Cookie: PHPSESSID=b4e4fbd93540 |
包含格式为 的 Cookie-值对Cookiename=value 是存储在客户端和服务器端的数据,充当标识符。每次请求时,Cookie 都会传递给服务器,从而维护客户端的访问权限。Cookie 还可以用于其他用途,例如保存用户偏好设置或会话跟踪。单个标头中可以包含多个 Cookie,并以分号分隔。 |
Authorization |
Authorization: BASIC cGFzc3dvcmQK |
这是服务器识别客户端的另一种方法。身份验证成功后,服务器会返回一个客户端独有的令牌。与 Cookie 不同,令牌仅存储在客户端,服务器会根据请求检索令牌。根据所使用的 Web 服务器和应用程序类型,身份验证类型有多种。 |
响应标头
标题 | 例子 | 描述 |
---|---|---|
Server |
Server: Apache/2.2.14 (Win32) |
包含处理请求的 HTTP 服务器的信息。它可用于获取服务器信息(例如其版本),并进一步枚举服务器。 |
Set-Cookie |
Set-Cookie: PHPSESSID=b4e4fbd93540 |
包含客户端识别所需的 Cookie。浏览器会解析这些 Cookie 并将其存储起来,以供将来的请求使用。此标头的格式与Cookie 请求标头相同。 |
WWW-Authenticate |
WWW-Authenticate: BASIC realm="localhost" |
通知客户端访问所请求资源所需的身份验证类型。 |
安全标头
标题 | 例子 | 描述 |
---|---|---|
Content-Security-Policy |
Content-Security-Policy: script-src 'self' |
指示网站对外部注入资源的策略。这些资源可以是 JavaScript 代码,也可以是脚本资源。此标头指示浏览器仅接受来自某些受信任域的资源,从而防止跨站点脚本 (XSS)等攻击。 |
Strict-Transport-Security |
Strict-Transport-Security: max-age=31536000 |
阻止浏览器通过纯文本 HTTP 协议访问网站,并强制所有通信通过安全的 HTTPS 协议进行。这可以防止攻击者嗅探网络流量并访问受保护的信息(例如密码或其他敏感数据)。 |
Referrer-Policy |
Referrer-Policy: origin |
指示浏览器是否应包含通过标头指定的值Referer 。它有助于避免在浏览网站时泄露敏感的 URL 和信息。 |
请求方法
方法 | 描述 |
---|---|
GET |
?param=value 请求特定资源。可以通过 URL 中的查询字符串(例如)向服务器传递附加数据。 |
POST |
向服务器发送数据。它可以处理多种类型的输入,例如文本、PDF 和其他形式的二进制数据。这些数据会附加到请求体中,位于请求头之后。POST 方法通常用于发送信息(例如表单/登录信息)或向网站上传数据(例如图片或文档)。 |
HEAD |
请求向服务器发出 GET 请求时返回的标头。它不返回请求正文,通常用于在下载资源之前检查响应长度。 |
PUT |
在服务器上创建新资源。如果在未进行适当控制的情况下允许此方法,则可能导致上传恶意资源。 |
DELETE |
删除 Web 服务器上的现有资源。如果安全措施不完善,可能会删除 Web 服务器上的关键文件,从而导致拒绝服务 (DoS)。 |
OPTIONS |
返回有关服务器的信息,例如服务器接受的方法。 |
PATCH |
对指定位置的资源应用部分修改。 |
响应代码
类型 | 描述 |
---|---|
1xx |
提供信息并且不影响请求的处理。 |
2xx |
请求成功时返回。 |
3xx |
当服务器重定向客户端时返回。 |
4xx |
表示不适当的请求from the client 。例如,请求不存在的资源或请求错误的格式。 |
5xx |
当其本身出现问题时就退货with the HTTP server 。 |
以下是上述每种 HTTP 方法类型的一些常见示例:
代码 | 描述 |
---|---|
200 OK |
请求成功后返回,响应主体通常包含所请求的资源。 |
302 Found |
将客户端重定向到另一个 URL。例如,在用户成功登录后将用户重定向到其仪表板。 |
400 Bad Request |
遇到格式错误的请求(例如缺少行终止符的请求)时返回。 |
403 Forbidden |
表示客户端没有对资源的适当访问权限。当服务器检测到用户的恶意输入时,也会返回此错误。 |
404 Not Found |
当客户端请求服务器上不存在的资源时返回。 |
500 Internal Server Error |
当服务器无法处理请求时返回。 |
CRUD API
增删改查
手术 | HTTP 方法 | 描述 |
---|---|---|
Create |
POST |
将指定的数据添加到数据库表 |
Read |
GET |
从数据库表中读取指定实体 |
Update |
PUT |
更新指定数据库表的数据 |
Delete |
DELETE |
从数据库表中删除指定行 |
读
可以在 API 后简单地指定表名(例如/city
),然后指定我们的搜索词
为了将其正确格式化为 JSON 格式,我们可以将输出通过管道传输到jq
实用程序,实用程序会对其进行正确格式化。我们还将使用 来抑制任何不需要的 cURL 输出-s
增加
1 | curl -X POST http://<SERVER_IP>:<PORT>/api.php/city/ -d '{"city_name":"HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json' |
更新
1 | curl -X PUT http://<SERVER_IP>:<PORT>/api.php/city/london -d '{"city_name":"New_HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json' |
[!NOTE]
注意: HTTP
PATCH
方法也可以用于更新 API 条目,而不是PUT
。确切地说,PATCH
用于部分更新条目(仅修改部分数据,例如仅修改 city_name),而PUT
用于更新整个条目。我们也可以使用 HTTPOPTIONS
方法来查看服务器接受哪种方法,然后相应地使用相应的方法。
删除
1 | curl -X DELETE http://<SERVER_IP>:<PORT>/api.php/city/New_HTB_City |
cURL
cURL(客户端 URL)是一个命令行工具和库,主要支持 HTTP 以及许多其他协议。它 不像 Web 浏览器那样渲染 HTML/JavaScript/CSS 代码,而是以原始格式打印出来
1.可以将任何 URL 作为 cURL 的参数,向其发送基本 HTTP 请求
2.可以使用 cURL 下载页面或文件,并使用-O
标志将内容输出到文件中。如果要指定输出文件名,可以使用-o
标志并指定文件名。否则,我们可以使用-O
,cURL 将使用远程文件名
3.注意到 cURL 在处理请求时仍然打印了一些状态。我们可以使用-s
标志来关闭这些状态
4.-v
在之前的命令中添加 verbose 标志,它就会同时打印请求和响应(-vvv可以更加详细)
5.可以使用该-I
标志发送HEAD
请求并仅显示响应头。我们还可以使用该-i
标志同时显示响应头和响应主体(例如 HTML 代码)。两者的区别在于,cURL-I
发送HEAD
请求,而 cURL-i
发送我们指定的任何请求并打印响应头。
6.使用-H
标志设置请求标头。某些标头(例如User-Agent
或Cookie
标头)有自己的标志。例如,我们可以使用-A
来设置我们的User-Agent
又例如手动设置Authorization
。我们可以使用-H
标志设置标头,并将使用来自上述 HTTP 请求的相同值,可以-H
多次添加标志以指定多个标头
7..可以使用该-h
标志来查看 cURL 还有哪些其他选项(可以使用--help all
来打印更详细的帮助菜单,或者--help category
(例如-h http
)打印特定标志的详细帮助。如果我们需要阅读更详细的文档,可以使用man curl
来查看完整的 cURL 手册页)
超文本传输安全协议 (HTTPS)
HTTPS 流程
如果我们输入http://
而不是https://
来访问一个强制使用 HTTPS 的网站,浏览器会尝试解析域名并将用户重定向到托管目标网站的 Web 服务器。请求80
首先发送到端口,这是未加密的 HTTP 协议。服务器检测到这种情况后,会将客户端重定向到安全的 HTTPS 端口443
。这是通过301 Moved Permanently
响应代码完成的
接下来,客户端(Web 浏览器)发送一个“客户端 hello”数据包,提供自身的相关信息。之后,服务器回复“服务器 hello”,并进行密钥交换以交换 SSL 证书。客户端验证密钥/证书后,再发送自己的密钥/证书。之后,发起加密握手,以确认加密和传输是否正常。
握手成功完成后,正常的 HTTP 通信将继续,之后的通信将被加密
HTTPS 的 cURL
1.cURL 应该自动处理所有 HTTPS 通信标准,执行安全握手,然后自动加密和解密数据。但是,如果我们访问的网站 SSL 证书无效或过期,cURL 默认不会继续进行通信,以防止前面提到的 MITM 攻击
2.要跳过使用 cURL 的证书检查,我们可以使用以下-k
标志
浏览器开发者工具
。要在 Chrome 或 Firefox 中打开浏览器开发者工具,我们可以点击 [ CTRL+SHIFT+I
] 或直接点击 [ F12
]
选项Network
卡,负责处理 Web 请求。
如果我们点击网络选项卡并刷新页面,我们应该能够看到页面发送的请求列表,还可以使用Filter URLs
来搜索特定的请求,以防网站加载过多而无法处理。