Loading... ## 1. HTTP 介绍 超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。 它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果。 它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。 ## 2. HTTP协议 ### 2.1 URL 与 URI - URI(Uniform Resource Identifier):统一资源标识符 - URL(Uniform Resource Locator):统一资源定位符 > URL是URI的子集 ### 2.2 URI 的格式 一个标准的网络请求如下: ``` <scheme>://<user>:<password>@<host>:<port>/<path>?<query>#<frag> ``` 各个字段的说明如下: | 字段 | 说明 | | ---------------------- | -------------------------------------------------- | | scheme | 该请求所用的协议名。如 http/https, ftp 等 | | user:password@ | 登录信息(认证),一般都不需要 | | host | 服务器地址。域名或者IP | | port | 服务器端口号,默认为80端口 | | path | 带层次的文件路径,指定服务器上的文件路径来定位资源 | | query | 查询的字符串。使用查询字符串传入参数 | | frag | 标记以获取资源中的子资源(文档内的某个位置) | 举个例子: ![URI.png](https://blog.domineto.top/usr/uploads/2019/09/2497683072.png) 实际使用过程中并不是所有的都需要的。对于http协议,主要的包括**scheme(协议)、host(主机)和path(资源路径)** 即可。 ### 2.3 HTTP协议工作流程 1. 客户端连接到Web服务器 2. 发送HTTP请求 3. 服务器接受请求并返回HTTP响应 4. 释放连接TCP连接 5. 客户端浏览器解析HTML内容 ![HTTP.png](https://blog.domineto.top/usr/uploads/2019/09/1096817821.png) ## 3. HTTP报文 ### 3.1 HTTP请求 HTTP 的请求报文分为三个部分: **请求行**,**请求头**和**请求体**。格式如下: ![HTTP请求报文格式.jpg](https://blog.domineto.top/usr/uploads/2019/09/1610835080.jpg) 举例如下: ![Snipaste_2019-09-17_19-48-55.png](https://blog.domineto.top/usr/uploads/2019/09/2889807511.png) ### 3.2 请求行 请求行(Request Line)分为三个部分:**请求方法**、**请求地址** 和 **协议及版本**,以CRLF(`\r\n`)结束。 HTTP/1.1 定义的请求方法有8种:**GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE**,最常的两种GET和POST。 #### 3.2.1 GET GET是最常用的方法,通常用于请求服务器发送某个资源。 ![Snipaste_2019-09-17_19-48-55.png](https://blog.domineto.top/usr/uploads/2019/09/2889807511.png) #### 3.2.2 POST POST是常用的方法之一,用于向服务端提交数据,有 body 部分。 ![Snipaste_2019-09-17_20-10-09.png](https://blog.domineto.top/usr/uploads/2019/09/2412822518.png) #### 3.2.3 HEAD 与GET类似,但在响应中只有首部,不返回具体数据,可以用来查看资源是否存在 #### 3.2.4 PUT/TRACE/OPTIONS/DELETE ``` PUT:用于向服务端写入文档 TRACE:用于跟踪某个请求 OPTIONS:用于查询服务端支持的方法 DELETE:用于删除服务端某个资源 ``` ### 3.3 请求头 请求头(Header)可用于传递一些附加信息,格式: `Key: value`。(**注意冒号后面的空格**) #### 3.3.1 请求和响应的常见通用Header | 名称 | 作用 | | | ---------------- | ------------------------------------------------------------ | ---- | | Content-Type | 请求体/响应体的类型,如:text/plain、application/json | | | Accept | 说明接收的类型,可以多个值,用`,`(半角逗号)分开 | | | Content-Length | 请求体/响应体的长度,单位字节 | | | Content-Encoding | 请求体/响应体的编码格式,如gzip,deflate | | | Accept-Encoding | 告知对方我方接受的Content-Encoding | | | ETag | 给当前资源的标识,和`Last-Modified`、`If-None-Match`、`If-Modified-Since`配合,用于缓存控制 | | | Cache-Control | 取值为一般为`no-cache`或`max-age=XX`,XX为个整数,表示该资源缓存有效期(秒) | | #### 3.3.2 常见请求Header | 名称 | 作用 | | ----------------- | ------------------------------------------------------------ | | Authorization | 用于设置身份认证信息 | | User-Agent | 用户标识,如:OS和浏览器的类型和版本 | | If-Modified-Since | 值为上一次服务器返回的 `Last-Modified` 值,用于确认某个资源是否被更改过,没有更改过(304)就从缓存中读取 | | If-None-Match | 值为上一次服务器返回的 ETag 值,一般会和`If-Modified-Since`一起出现 | | Cookie | 已有的Cookie | | Referer | 表示请求引用自哪个地址,比如你从页面A跳转到页面B时,值为页面A的地址 | | Host | 请求的主机和端口号 | #### 3.3.3 常见响应Header | 名称 | 作用 | | ----------------- | ------------------------------------------------------------ | | Date | 服务器的日期 | | Last-Modified | 该资源最后被修改时间 | | Transfer-Encoding | 取值为一般为chunked,出现在Content-Length不能确定的情况下,表示服务器不知道响应版体的数据大小,一般同时还会出现`Content-Encoding`响应头 | | Set-Cookie | 设置Cookie | | Location | 重定向到另一个URL,如输入浏览器就输入[baidu.com](http://baidu.com/)回车,会自动跳到 [https://www.baidu.com](https://www.baidu.com/) ,就是通过这个响应头控制的 | | Server | 后台服务器 | ### 3.4 请求体 根据应用场景的不同,HTTP请求的请求体有三种不同的形式。 #### 第一种: 移动开发者常见的,请求体是任意类型,服务器不会解析请求体,请求体的处理需要自己解析,如 POST JSON时候就是这类。 ![Snipaste_2019-09-17_20-19-35.png](https://blog.domineto.top/usr/uploads/2019/09/3804185627.png) #### 第二种: 第二种和第三种都有固定格式的,是服务器端开发人员最先了解到的两种。这里的格式要求就是URL中Query String的格式要求:多个键值对之间用`&`连接,键与值之前用`=`连接,且只能用ASCII字符,非ASCII字符需使用`UrlEncode`编码。 ![HTTP请求2.jpg](https://blog.domineto.top/usr/uploads/2019/09/187216528.jpg) #### 第三种: 第三种请求体的请求体被分成为多个部分,**文件上传**时会被使用,这种格式最先应该是被用于邮件传输中,每个字段/文件都被boundary(`Content-Type`中指定)分成单独的段,每段以`--` 加 boundary开头,然后是该段的描述头,描述头之后空一行接内容,请求结束的标制为boundary后面加`--`,结构见下图: ![HTTP请求3.jpg](https://blog.domineto.top/usr/uploads/2019/09/608686824.jpg) 区分是否被当成文件的关键是`Content-Disposition`是否包含`filename`,因为文件有不同的类型,所以还要使用`Content-Type`指示文件的类型,如果不知道是什么类型取值可以为`application/octet-stream`表示该文件是个二进制文件,如果不是文件则`Content-Type`可以省略。 ## 4. HTTP状态码 > 状态码是响应报文中对请求所做事情的处理结果,以方便客户端处理响应数据 状态码分为五大类: | 状态码 | 含义 | | :----- | :--------------------------------------------- | | 100s | 服务器响应信息,通常表示服务器还有后续处理信息 | | 200s | 请求被服务器成功接收并处理后返回的响应结果 | | 300s | 重定向 | | 400s | 客户端请求错误 | | 500s | 服务器内部错误 | 更多状态码的详细信息可以在[这里]( http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html )找到。 ## 5. Referrer https://www.jianshu.com/p/e544b7a76dac https://www.cnblogs.com/TomSnail/p/6078395.html 最后修改:2019 年 09 月 17 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏