反骨仔

一个业余的 .NET Core 攻城狮

0%

03 HTTP 协议请求方法和状态码

HTTP 请求方法、状态码和首部(Header)是互相配合、一起工作的。浏览器客户端通过 HTTP 方法告诉服务器要执行什么动作,服务器通过状态码来告诉浏览器客户端动作是否执行成功。

3.1 URL 详解

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

Internet 上的每个网页都有一个标识,一般称之为 URL 地址,或者 Web 地址,俗称“网址”。URL 地址可以是本地磁盘,也可以是局域网上的某一台计算机,更多的是 Internet 上的站点 。

URI 的全称是 Uniform Resource Identifier,中文译名为“统一资源标识符“用来唯一地标识一个资源。而 URL 是一种具体的 URI 。

我们可以简单地把 URI 和 URL 看作同一个东西 。

3.1.1 URL 格式

URL 的基本格式如下:

1
schema://host[:port#]/path/.../[?query-string][#anchor]
描述
schema 指定低层使用的协议(例如 :http, https, ftp)
host HTTP 服务器的 IP 地址或者域名
port# HTTP 服务器的默认端口是 80,这种情况下端口号可以省略。如果使用了别的端口,则必须指明,例如 http://www.cnblogs.com:8080/
path 访问资源的路径
query-string 发送给 http 服务器的数据
anchor

URL 的一个例子如下 :

1
http://www.mywebsite.com/liqingwen/test/test.aspx?narne=sviergn&x=true#stuff
描述
Schema(协议) http
host (域名) www.mywebsite.com
path(资源的路径) /liqingwen/test/test.aspx
Query String(参数) name=sviergn&x=true
Anchor(锚) stuff

3.1.2 URL 中的锚点

锚点(Anchor)是一种超链接,只是它是页面内部的超链接。

假如有一个网页很长,而且里面的内容可以分为 N 个部分。这样的话,我们就可以在网页的顶部设置一些锚点,以便浏览者单击相应的锚点,快速到达本页内相应的位置,而不必在一个很长的网页里自行寻找。

锚点在 URL 的最右边,前面有一个字符“#”。

比如下面的 #source:http://www.cnblogs.com/liqingwen/p/7087990.html#source

3.2 HTTP 请求方法

HTTP 协议中定义了几种不同的请求命令,这些命令叫作 HTTP 方法 CHTTP Method)。每个 HTTP 请求报文中都包含一个方法,这个方法会告诉服务器要执行什么动作,如是要获取一个 Web 页面还是要删除一个文件。

HTTP 协议定义了很多与服务器交互的方法,最基本的有 5 种, 分别是 GET 、 HEAD 、POST 、PUT 、DELETE 。一个 URL 地址用于描述一个网络上的资源,而 HTTP 中的 GET、POST、PUT、DELETE 就对应着对这个资源的查、改、增、删 4 个操作。最常见的是 GET 和 POST 。GET 一般用于获取/查询资源信息,而 POST 一般用于更新资源信息。

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

3.2.1 GET 方法

GET 是最常见的方法,用于获取资源,常用于向服务器查询某些信息。

image-20210102180234441

启动 Fiddler,打开浏览器,输入 http://www.669.icu。从 Fiddler 中可以看到浏览器发出的是 GET 方法。

image-20210116150942966

打开网页一般都是用 GET 方法,因为要从 Web 服务器获取信息。

3.2.2 带参数的 GET 方法

浏览器也可以在 GET 方法中把数据传给服务器,数据放在 URL 的问号(?)后面 。

将查询字符串参数追加到 URL 末尾,以便将信息发送给服务器。这种方式叫查询字符串,或者叫 Query String。

百度中某搜索 URL 如下

1
https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E4%BD%A0%E5%A5%BD&fenlei=256&rsv_pq=8187eb1f001397cd&rsv_t=3f8e8T5zasKgSnEB9un5%2FDUp%2F1Z5B9z%2BvLILeBJCEeAJv5l%2FMUpFF%2B5AIT4&rqlang=cn&rsv_enter=1&rsv_dl=ts_0&rsv_sug3=6&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&prefixsug=nih&rsp=0&inputT=5314&rsv_sug4=5315

查询字符串以“名=值”这样的形式出现,多个名值之间用字符“&"隔开。

在 Fiddler 中,使用 WebForms 选项卡可以更清楚地看到 GET 方法中的查询字符串参数。

image-20210116150020346

3.2.3 POST 方法

POST 方法通常用来把表单中填好的数据发送给服务器 。

启动 Fiddler,打开浏览器,输入 http://www.669.icu/posttest,输入用户名和密码 , 然后单击登录。

image-20210102180949261

我们可以清晰地看到浏览器发出的是 POST 方法,该方法把用户名和密码的信息发送给了服务器。

image-20210102181018330

使用 WebForms Tab 可以更清楚地看到 Body 主体里面的内容。

image-20210102181056888

3.2.4 GET 和 POST 方法的区别

GET 和 POST 的区别主要表现在如下方面:

  • GET 提交的数据会放在 URL 之后,以问号(?)分割 URL 和传输数据 ,参数之间以&相 连 ,如 EditPosts.aspx?name=testl&id=123456。POST 方法是把提交的数据放在 HTTP 包的 Body 中
  • GET 提交 的数据大小有限制(因为浏览器对 URL 的长度有限制),而 POST 方法提交的数据大小没有限制
  • GET 方式需要使用 Request.QueryString 来取得变量的值 ,而 POST 方法通过 Request.Form 来获取变量的值
  • GET 方式提交数据会带来安全问题,比如一个登录页面通过 GET 方式提交数据时,用户名和密码将出现在 URL 上 ,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码。

3.3 HTTP 状态码

3.3.1 什么是 HTTP 状态码

每个 HTTP 响应报文都会携带一个状态码,用于告诉客户端请求是否成功。状态码是一个 3 位数字的代码。

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

HTTP 响应报文中的第一行,由 HTTP 协议版本号、状态码 、状态消息 3 部分组成。状态码用来告诉 HTTP 客户端 Web 服务器是否产生了预期的 HTTP 响应。

3.3.2 状态码分类

HTTP/1.1 中定义了 5 类状态码,状态码由 3 位数字组成 ,第一个数字定义了响应的类别。

HTTP 状态码被分为 5 大类 , 支持如表 3-2 所示的状态码。随着协议的发展 ,HTTP 规范 中会定义更多的状态码 。

image-20210102181628213

3.3.3 常见的状态码

image-20210102181705286

3.3.4 200 (OK)

最常见的状态码就是成功响应状态码 200 了 ,它表明该请求被成功地完成 ,所请求的资源成功地发送回客户端 。

image-20210102181808010

3.3.5 204(No Content,没有内容)

返回的 HTTP 响应中只有一些 Header 和一个状态行,美有实体的主题内容(没有响应 Body)。

204 状态码的作用如下:

  1. 在不获取资源的情况下了解资源的情况(比如判断其类型)
  2. 通过查看 HTTP 响应中的状态码看某个对象是否存在
  3. 通过查看 Header 测试资源是否被修改

【实例】启动 Fiddler,启动浏览器访问 http://www.google.cn,会捕获到很多 204。

image-20210102182526077

3.3.6 206 ( Partial Content,部分内容)

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

206 的应用场景如下:

  1. FlashGet、迅雷或者 HTTP 下载工具都是使用 206 状态码来实现断点续传的

  2. 将一个大文档分解为多个下载段同 时下载,比如在线看视频。

实例 :如图 3-9 所示,一些流媒体技术, 比如在线视频可以边看边下载,就是使用 206 状态码来实现的。

image-20210102182714532

启动 Fiddler,然后用浏览器打开“搜狐视频中的绿箭侠” http://tv.sohu.com/20121011/n354681393.shtml,会发现 Fiddler 中就能看到一堆的 206。

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

3.3.7 301 (Moved Permanently)

服务器返回 301 的时候,表示请求的网页己经永久性地转移到另一个地址。

在如下情况下需要用到 301。

  1. 防止用户输错域名。比如 Google 担心用户输错域名 ,就把其他类似的域名买下来,比如 www.goOgle.com ,然后重定向到 www.google.com
  2. 网站更换域名 。一些网站壮大后 ,会换个更好的域名。比如京东以前的域名是 www.360buy.com,现在的域名是 www.jd.com
  3. 有多个权重不错的域名,需要把所有的权重都传递到新域名上,这就需要 301 重定向了。如果不设置 301,多个域名绑定在一个主机头上,会被搜索引擎认为是两个相同的站点,不利于网站的排名 。 绑定的域名越多,内 容重复度也就越高,排名越低 。

【实例】查看京东的老域名跳转到新域名:

启动 Fiddler ,在浏览器中输入 http://www.360buy.com

image-20210102183723426

  1. 浏览器发送请求访问 www.360buy.com,服务器返回 301 ,并且 Location 是 www.jd.com
  2. 浏览器会读取 Location 中的 URL,自动发送一个新的 HTTP?请求去访问 www.jd.com

3.3.8 302 ( Found )

当我们访问 一个 URL 的时候,服务器要我们访问另 一个资源 ,这时候浏览器会继续发一个 HTTP ,请求访 问 新的资源 。

【实例】在未登录状态下,直接访问需要登录才能访问的页面,会被服务器返回 302 ,跳转到登录页面 。 具体操作步骤如下。

image-20210102185851371

  1. 启动 Fiddler,打开浏览器,直接在地址栏中输入 https://i.cnblogs.com/

  2. 在 Fiddler 中可以看到服务器返 回 302 ,井且 Location=/user/signin?ReturnUrl=%2f(告诉客户端,新的资源在这里)

  3. 浏览器会自动再发送一个新的 HTTP 请求一一去访问 https://i.cnblogs.com/user/signin?ReturnUrl=%2F

3.3.9 301 和 302 的区别

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

区别在于:

  • 301 表示旧地址的资源己经被永久地移除了(这个资源不可访问了),搜索引擎会把权重算到新地址;
  • 302 表示 旧地址的资源还在(仍然可以访问),这个重定向只是临时地从旧地址跳转到新地址,搜索引擎会把权重算到旧地址。

3.3.10 304 (Not Modified)

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

例如打开博客园首页,会发现很多 HTTP 响应的状态码都是 304 ,如图所示 。304 的响应是没有 Body 的 。

image-20210102190301505

如果你不想使用本地缓存,可以用【Ctrl+F5】组合键强制刷新页面。

3.3.11 400 (Bad Request)

状态码 400 表示客户端请求有语法错误,发送的 HTTP 请求中的数据有错误(如表单有错误、Cookie 有错误)。不能被服务器所理解。

【实例】快递查询接口,如果参数不对 ,服务器会返回 400 状态码 。

打开 Fiddler ,在浏览器中输入 http://www.kuaidi100.com/query?type=xxx。

image-20210102190550135

3.3.12 401(Unauthorized)

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

image-20210102190704480

3.3.13 403 (Forbidden)

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

访问 URL:http://t2.baidu.com/it/u=1791561788,200960144&fm=0&gp=0.jpg,会被服务器拒绝,并且返回 403 状态码。

image-20210102190914993

3.3.14 404 ( Not Found )

当你访问一个 URL ,这个 URL 的域名是正确的,但是资源不存在,服务器就会返回 404 状态码,告诉浏览器资源不存在(意味着输错了 URL)。

启动 F iddler,输入 http://www.cnblogs/tankxiao/p/888.html(888.htrnl 这个文件在服务器上不存在〉。

如图所示,我们可以看到 Web 服务器会返回 404 状态码,这个 404 页面是可以自定义的。

image-20210102191123002

3.3.15 500 (Internal Server Error)

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

当数据库连接不成功的时候,服务器返回 500 状态码 。

image-20210102191227974

3.3.16 503(Server Unavailable)

状态码 503 表示服务器暂时不可用 。由于服务器维护或者过载,服务器当前无法处理请求 ;这个状况是临时的,并且将在一段时间以后恢复。

image-20210102191330535

参考

  • 《HTTP 抓包实战》