HTTP学习
本文最后更新于 808 天前,其中的信息可能已经有所发展或是发生改变。

引言

这是在我阅读了肖佳老师的书《HTTP抓包实战》后对HTTP相关内容的总结,主要还是报文相关(记录:阅读此书与写出此文章耗时5天)

HTTP协议报文的结构

HTTP报文分2个:一个是HTTP请求报文,一个是HTTP响应报文

HTTP请求报文(Request)

HTTP请求报文分为3个部分,第一部分叫起始行(Request line),第二部分叫首部(Request Header),第三部分叫主体(Body)

  • 第一行中有Method(请求方法)、URI和协议版本。例如GET https://blog.yexca.xyz/ HTTP/2
  • 第二部分是Header(首部)
  • 第三部分是Body(主体)

注意:Header首部和Body主体之间有一个空行

HTTP响应报文(Responese)

HTTP响应报文与请求报文的结构基本一样,也分为3个部分,第一部分叫响应行(Response line),第二部分叫响应首部(Response Header),第三部分是0主体(Body)

  • 第一行有协议版本、状态码和状态码消息。例如HTTP/2 200
  • 第二部分是Header(首部)
  • 第三部分是Body(主体)

注意:Header首部和Body主体之间有一个空行

HTTP协议请求方法和状态码

URL格式

URL的全称为Uniform Reasource Locator,中文译名为统一资源定位符,用于完整地描述Internet上某一处资源的地址

URL的基本格式如下:

schema://host[:port#]/path/.../[?query-string][#anchor]

属性描述
schema(协议)指定底层使用的协议(例如:http,https,ftp)
host(域名)HTTP服务器的IP地址或者域名
port#(端口)HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,则必须指明
path(资源的路径)访问资源的路径
query-string(参数)发送给HTTP服务器的数据
anchor(锚)锚,页面内部超链接

HTTP请求方法

方法描述
1GET请求指定的页面信息并返回实体主体
2HEAD类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头
3POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或对已有资源的修改
4PUT从客户端向服务器传送的数据取代指定文档的内容
5DELETE请求服务器删除指定的页面

GET与POST的区别

  1. GET提交的数据会放在URL之后,以?分隔URL和传输数据(即query-string,键值对方式),参数之间以&相连 而POST方法是把提交的数据放在HTTP包的Body中
  2. GET提交的数据大小有限制(因为浏览器对URL的长度有限制) 而POST方法提交的数据大小没有限制
  3. GET方式需要使用Request.QueryString来取得变量的值 而POST方法通过Request.Form来获取变量的值

HTTP状态码

HTTP状态码存在于HTTP的响应报文中,其作用是Web服务器用来告诉客户端发生了什么事

HTTP状态码被分为5大类,随着协议的发展,HTTP规范中会定义更多的状态码吧

状态码已定义范围分类
1XX100~101信息提示,表示请求已被成功接收,继续处理
2XX200~206成功,表示请求已被成功接收、理解、接受
3XX300~305重定向,要完成请求,必须进行进一步的处理
4XX400~415客户端错误,请求有语法错误或请求无法实现
5XX500~505服务器错误,服务器未能实现合法的请求

常见状态码

名称释义
200OK:服务器成功处理了请求
301/302Moved Permanently(重定向):请求的URL已移走。Response中应该包含一个Location URL,说明资源现在所处的位置
304Not Modified(未修改):客户端的缓存资源是最新的,需要客户端使用缓存
404Not Found:未找到资源
401禁止访问
501Internal Server Error:服务器遇到一个错误,使其无法对请求提供服务

206(Partial Content,部分内容)

206状态码代表服务器已经成功处理了部分GET请求(只有发送GET方法的HTTP请求,Web服务器才可能返回206)

应用比如说使用下载工具实现断点续传或者在线视频播放都是使用206状态码来实现

例如现在打开视频网站的一个视频,对于视频所在的URL

  1. 浏览器会发送一个GET请求,Header中包含Range: bytes=5303296-5336063,意思就是请求得到5303296-5336063之间的数据
  2. Web服务器返回一个206的HTTP响应。Header中包含Content-Range: bytes 5303296-5336063/12129376,表明这次返回的内容范围

301与302(Moved Permanently,重定向)

在得到301或302响应后,浏览器会再次请求位于Location中返回新的URL

状态码301和302在语法上是一模一样的,都是在HTTP响应的Location中返回新的URL

区别在于:

  • 301表示旧地址已经被永久移除了,这个资源不可访问了,搜索引擎会把权重算到新地址 例如:防止用户输错域名或更换域名
  • 302表示旧地址的资源还在,仍然可以访问,这个重定向只是临时地从旧地址跳转到新地址,搜索引擎会把权重算到新地址 例如:未登录状态下访问需要登陆才能访问的页面

304(Not Modified,未修改)

状态码304表示上次的文档已经被缓存了,还可以继续使用

400(Bad Request)

状态码400表示客户端请求有语法错误,发送的HTTP请求中的数据有错误,例如表单有错误或者Cookie有错误,不能被度武器所理解

401(Unauthorized)

状态码401是指为授权错误。有些网页采用的是HTTP基本认证(Basic Authentication),需要在HTTP请求Header中带上Authentication,否则服务器会返回状态码401

404(Not Found)

该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求但不想说明理由时使用

例如BV1AB4y1D7Ft这个视频仅在登录并且收藏的情况下才可见,否则将返回404

403(Forbidden)

状态码403表示Web客户端发送的请求被Web服务器拒绝了。如果服务器想说明为什么拒绝请求,可以在Body中描述原因。但这个状态码通常表示服务器不想说明拒绝原因

500(Internal Server Error)

状态码500代表服务器内部错误。出现错误的原因有很多,比如代码的错误、数据库连接语句出错、程序内部抛出异常、空指针错误等

503(Server Unavailable)

状态码503表示服务器暂时不可用。由于服务器维护或者过载,服务器目前无法处理请求

这个状况是临时的,并且将在一段时间以后恢复

了解全部状态码

访问:HTTP 状态码 | 菜鸟教程

HTTP协议Header

Header的语法格式是“key: value”,一行一个。每一个Header都有特殊的作用

Cache相关的Header

HTTP请求与HTTP响应都有很多用于缓存的Header。HTTP缓存是指当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是原始服务器中获取该文件

Cookie是一种HTTP Cache,是HTTP中非常重要的内容。它由key=value的形式组成,比如ip_country=CN

浏览器把Cookie通过HTTP请求中的“Cookie: header”发送给Web服务器,Web服务器通过HTTP响应中的“Set-Cookie: header”把Cookie发送给浏览器

Accept

Accept表示浏览器客户端可以接受的媒体类型。例如Accept: text/html代表可以接受服务器返回html

通配符*代表任意类型,例如Accept: text/html,\/*;q=0.8*代表浏览器可以处理所有的类型。一般浏览器客户端给Web服务器发送的都是类似这个

Accept-Encoding

Accept-Encoding跟压缩有关,浏览器发送HTTP请求告诉Web服务器浏览器支持的压缩形式,例如Accept-Encoding: gzip, deflate

Accept-Language

Accept-Language作用是声明自己接受的语言。注意语言与字符集的区别,中文是语言,中文有多种字符集,例如GB2312、GBK等。例如Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2

User-Agent

User-Agent的作用是浏览器用来告诉服务器,客户端使用的操作系统及版本、CPU类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等

例如User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0代表64位Linux系统,Firefox是103.0版本

如果想要模拟各种不同的客户端,只要修改User-Agent,就可以伪装成各种客户端

Referer

Referer主要用来让服务器判断来源页面,即用户是从哪个页面来的,网站通常用其统计用户来源,也可以用作放盗链等

Connection

从HTTP/1.1起,系统默认都开启了Connection: Keep-Alive,保持连接特性。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间

Host

Host的作用是指定被请求的主机和端口号,如果是80端口号会被自动隐藏

HTTP协议中的缓存

缓存无处不在,有浏览器端的缓存、服务器端的缓存、代理服务器的缓存,还有ASP.NET页面的缓存、对象缓存、数据库缓存等等

HTTP中具有缓存功能的是浏览器缓存和代理服务器缓存

HTTP缓存是指当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档

缓存的优点:减少了冗余的数据传输,节省了传输时间;减少了服务器的负担,大大提高了网站的性能;加快了客户端加载网页的速度等

如何判断缓存新鲜度

Web服务器通过以下两种方式来判断浏览器缓存是否最新

  1. 浏览器把缓存文件的最后修改时间通过HeaderIf-Modified-Since告诉Web服务器。浏览器收到HTTP请求后,在Header中将文件最后修改世界Last-Modified与请求报文的If-Modified-Since相比较。若相同则说明文件是最新的,则发送状态吗304(Not Modified)给浏览器客户端;若不同则发送状态码200把最新文件发送给浏览器客户端
  2. 浏览器把缓存文件的ETag通过HeaderIf-None-Match告诉Web服务器

与缓存有关的Header

  • HTTP请求报文Header
名称释义
Cache-Control: max-age=0以秒为单位
If-Modified-Since: Tue, 28 Jun 2022 00:50:56 GMT缓存文件的最后修改时间
If-None-Match: “1771e0c387823da5329c20a76bece83c”缓存文件的ETag值
Cache-Control: no-cache不使用缓存
Pragma: no-cache不使用缓存
  • HTTP响应报文Header
名称释义
Cache-Control: public响应被缓存,并且可以被多用户访问使用
Cache-Control: private响应只能作为私有缓存,特定用户使用
Cache-Control: no-cache提醒浏览器要从服务器提取文档进行验证
Cache-Control: no-store绝对禁止缓存(用于机密、敏感文件)
Cache-Control: max-age=6060s后缓存过期(相对时间)
Date: Thu, 01 Sep 2022 21:56:36 GMT当前响应发送的时间
Expires: Thu, 01 Sep 2022 21:57:37 GMT缓存过期的时间(绝对时间)
Last-Modified: Tue, 28 Jun 2022 00:50:56 GMT服务端文件的最后修改时间
Etag: “1771e0c387823da5329c20a76bece83c”服务器文件的ETag值

注:浏览器总是优先使用cache-control,如果没有时才考虑Expires

ETag

ETag是Entity Tag(实体标签)的缩写,是根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以表示文件的状态。当资源发生改变时,ETag也随之发生改变

使用ETag主要是为了解决一些Last-Modified无法解决的问题,比如说某些服务器不能精确得到文件的最后修改时间、一些文件最后修改时间改变了但是内容不变、某些文件修改特别频繁甚至达到了以秒为单位以下等

注:Last-Modified只能精确到秒

浏览器不使用缓存

使用Ctrl+Shift+R快捷键强制刷新浏览器,可以让浏览器不使用缓存,即浏览器的HTTP请求报文的Header中带有Cache-Control: no-cache,明确告诉Web服务器不使用缓存

注:Pragma: no-cacheCache-Control: no-cache作用相同,只是Pragma: no-cache是HTTP/1.0定义的,保留为了兼容性

直接使用缓存,不经过服务器验证

使用Ctrl+R快捷键刷新浏览器,浏览器会去Web服务器验证缓存

如果在地址栏直接输入地址并访问,浏览器会“直接使用有效的缓存”,不会发送HTTP请求去服务器验证缓存,这种情况叫作缓存命中

公有缓存与私有缓存

公有缓存Cache-Control: public可以由多个用户共享访问,而私有缓存Cache-Control: private只能单个用户访问使用

HTTP协议压缩和URL Encode

HTTP压缩是指Web服务器和浏览器之间压缩传输文本内容的方法。HTTP采用通用的压缩算法,比如用gzip来压缩HTML、JavaScript、CSS文件

HTTP内容编码与压缩的区别

在HTTP协议中,可以对Body部分进行编码,如可以采用gzip这样的编码,从而达到压缩的目地;也可以使用其他编码方式把内容搅乱或加密,以此来防止未被授权的第三方看到文档的内容。所以HTTP压缩其实就是HTTP内容编码的一种

HTTP压缩的过程

  1. 浏览器发送HTTP请求Header中带Accept-Encoding: gzip,deflate告诉服务器浏览器支持gzip压缩
  2. Web服务器接到HTTP请求后,先生成原始的HTTP响应,包含原始的Content-TypeContent-Length;然后通过gzip对HTTP响应的Body进行编码,并在编码后Header中的Content-TypeContent-Length替换为压缩后的大小,以及加上编码方式Content-Encoding: gzip;再把HTTP响应发送给浏览器
  3. 浏览器接到HTTP响应后,根据Content-Encoding: gzip来对HTTP响应进行解码,获取到原始HTTP响应后显示出网页

注:HTTP请求也是可以编码的,但是浏览器一般不会对HTTP请求编码

内容编码类型

HTTP定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码

在Header中的Content-Encoding就是使用这些标准化的代号来说明编码时使用的算法

编码描述
gzip表明实体采用GNU zip编码
compress表明实体采用UNIX的文件压缩程序
deflate表明实体是用zlib的格式压缩的
identity表明没有对实体进行编码。当Header中没有Content-Encoding时,默认为此情况

gzip、compress以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息缺失。其中gzip通常效率最高,使用最为广泛

深入理解Cookie机制

HTTP协议是无状态的,对于浏览器的每一次请求,服务器都会独立处理,不与之前或之后的请求发生关联。即使是同一个浏览器发送了3个请求,服务器也会独立处理这3个请求,服务器并不知道这3个请求是来自同一个浏览器

会话机制与Cookie机制

服务器需要识别浏览器请求,就必须弄清楚浏览器的请求状态。既然HTTP协议是无状态的,那就让服务器和浏览器共同维护一个状态,这就是会话机制

  1. 浏览器第一次请求服务器时,服务器创建一个会话,并将会话ID作为响应的一部分发送给浏览器
  2. 浏览器存储会话ID,并在后续请求中带上会话ID
  3. 服务器取得请求中的会话ID就知道是不是同一个用户了

这样后续请求与第一次请求就产生了关联,而Cookie机制就是一种会话机制

服务器在内存中保存会话对象,浏览器可以使用Cookie机制保存会话ID

Cookie是什么

Cookie是浏览器用来存储少量数据的一种机制,数据以key=value形式存储,多个Cookie之间以分号;分隔,浏览器发送HTTP请求时自动附带Cookie信息

Cookie最主要的作用是用来做用户认证,还可以用于保存用户的一些其他信息。也可以用于互联网精准广告定向技术,例如用户浏览了某些商品,就可以用Cookie记录下来,然后进行大数据深度分析,实现广告精准投放

鉴于此项,目前欧洲的一些国家已经对Cookie立法,并规定必须经过用户的允许才可以保存用户的Cookie

Cookie的属性

根据网站不同,Cookie有所不同

  1. Expires

表示Cookie失效的时间,如果不指定则在关闭浏览器或页面时被浏览器删除

  1. Path

表示Cookie所属的路径,asp.net默认为/也就是根目录

假设在同一个服务器上的目录如下:/test//test/cd//test/dd,Cookie1的Path在/test/,Cookie2的在/test/cd/,那么/test/下的所有页面都可以访问到Cookie1,而/test/dd/的自页面不能访问Cookie2.因为Cookie只能让其Path路径下的页面访问

  1. HttpOnly

这是个关乎安全方面的属性,将一个Cookie设置为HttpOnly后,通过JavaScript脚本将无法读取到Cookie信息,这能有效防止用XSS发起攻击

一般来说,跟登录相关的Cookie必须设置为HttpOnly

Cookie的分类与位置

类别描述
会话Cookie临时的Cookie,记录了用户访问站点时的设置与偏好(例如访问本站时的Cookie),关闭浏览器后将被删除
持久Cookie存储在硬盘上,有过期时间。不管退出浏览器还是重启计算机都存在

网站的自动登录就是储存持久Cookie,在用户再次访问相同网站时会先在硬盘中查找相关Cookie然后放到HTTP请求报文中发送给服务器

那么持久Cookie存在计算机那里呢?不同浏览器会在各自的独立空间存放Cookie,互不干扰

例如Linux下Firefox的Cookie位置:~/.mozilla/firefox/xxxxxxxx.default-release/cookies.sqlite

HTTP基本认证

HTTP协议是无状态的,浏览器和Web服务器之间可以通过Cookie来识别身份。那么一些桌面应用程序是如何跟Web服务器之间识别身份呢?

一些网站和Web服务使用的是HTTP基本认证。有些桌面应用程序u也通过HTTP协议跟Web服务器交互,桌面应用程序一般不使用Cookie,而是把用户名+冒号+密码用Base64编码放在HTTP请求Header中的Authorization发送给服务端,这种方式叫HTTP基本认证(Basic Authentication)

在基本认证中,Web服务器可以拒绝一个事物,要求客户端提供有效的用户名和密码,服务器会返回401状态码来初始化认证质询,并用WWW-Authenticate响应首部指定要访问的安全域。浏览器收到质询时,会打开一个对话框请求用户输入用户名和密码,然后将用户名和密码用Base64编码,再用Authorization请求首部发送给服务器

一般家用路由器就是使用基本认证,RESTful API就经常使用基本认证,使用命令curl -u username:password URI即可完成基本认证

HTTP基本认证的缺点

  1. HTTP协议是无状态的,同一个客户端对服务器的每个请求都需要认证
  2. Base64编码是可逆的,非常容易破解,所以基本认证相当于以明文的方式传输用户名和密码。所以基本认证一定要用HTTPS加密传输,稍微安全一点
  3. 使用基本认证登录后,除非关闭浏览器或清除历史记录,否则无法登出。而Cookie机制的话,网站可以提供登出方式以使Cookie失效
  4. 无法防止重放攻击

摘要认证

摘要认证是针对基本认证存在的诸多问题而进行改良的方案。摘要认证是另一种HTTP认证协议,它试图修复基本认证的严重缺陷,进行如下改进

  1. 通过传递用户名、密码等计算出来的摘要来解决以明文方式在网络上发送密码的问题
  2. 通过服务器产生随机数nonce的方式防止恶意用户捕获并重放认证的握手过程
  3. 通过客户端产生随机数cnonce的方式支持客户端对服务器的认证
  4. 通过对内容也加入摘要计算的方式,可以有选择地防止对报文内容的篡改

参考文章

《图解HTTP》读后总结及浅谈 – yexca|Hiyoung‘Blog

HTTP 状态码 | 菜鸟教程

IE/Firefox/Chrome等浏览器保存Cookie的位置 – 脚本小娃子 – 博客园

“登录“还是“登陆“? – 知乎

重放攻击 – 维基百科,自由的百科全书

通俗易懂:到底什么是 REST API?

表现层状态转换 – 维基百科,自由的百科全书

本文链接:HTTP学习
本文章由 yexca 采用 知识共享署名 - 非商业性使用 - 相同方式共享 4.0 国际许可协议 进行许可,转载请注明出处。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇