文章目录
- 一. 认识 URL
- 1. URL 初识
- 2. URL 的组成
- ① 协议名称
- ② 域名
- ③ 端口号
- ④ 文件路径
- ⑤ 查询参数
- 3. URL中的字符
- 3.1 合法字符
- 3.2 保留字符
- 3.3 其他字符
- 3.4 URL中的字符总结
- 二. HTTP 协议
- 1. HTTP 介绍
- 2. 请求报文
- 2.1 请求报文的格式
- 2.2 请求方法介绍
- 2.3 请求报文中常见的 header
- Content-Type
- Content-Length
- Host
- User-Agent
- referer
- location
- Cookie
- 3. 响应报文
- 3.1 响应报文的格式
- 3.2. 常见状态码及状态码描述
- 1xx 信息
- 2xx 成功
- 3xx 重定向
- 4xx 客户端错误
- 5xx 服务器错误
一. 认识 URL
1. URL 初识
互联网上的每一个网页都具有一个唯一的名称标识,通常称之为 URL(Uniform Resource Locator, 统一资源定位器),中文译为“网址”,表示各种资源的互联网地址。
所谓资源,可以理解为各种可以通过互联网去访问的文件,比如网页(html)CSS、JS脚本、图像、音频、视频等。
只要资源可以通过互联网访问,它就必然有对应的 URL。一个 URL 对应一个资源,但是同一个资源可能包含多个其他的资源的 URL。互联网之所以“互联”,就是因为网页可以通过“链接”,去从一个 URL 跳转到另一个 URL,前往不同的网站获取和访问不同的资源。
2. URL 的组成
URL 由多个部分组成,下面是一个较完整的 URL:
① 协议名称
URL 中的协议指的是应用层协议,上例 https:// 的部分,表示使用 HTTPS 协议。应用层协议有多种,如果不指明的话,默认是 HTTP 协议。也就是说,如果省略协议,直接在浏览器地址栏输入www.example.com,那么浏览器默认会访问 http://www.example.com。
补充:协议名称的后面,会紧跟着一个冒号加两个斜杠 ://
,用来起到和后面字段分隔的作用。其它协议不一定如此,比如邮件地址协议 mailto 的后面就只有一个冒号用来分隔:mailto:foo@example.com。
② 域名
每个域名背后都对应着需要访问服务的服务器主机的 IP 地址。有些服务器主机没有域名,只有 IP 地址,比如192.168.2.15。这种情况常常出现在局域网。
既然域名和 IP 地址对应,直接用 IP 地址不就完了吗,为啥还要整个域名?你只要想想你经常使用的www.baidu.com
就可以了, 这个可比它的 IP 地址(36.152.44.95
)方便记忆多了。
访问网站只需要输入域名即可,浏览器会自动解析域名对应的 IP 地址找到对应的服务器主机,这具体是怎么解析的呢?通过域名解析系统 DNS(Domain Name System)来完成,它的作用非常简单,就是根据域名查出对应的 IP 地址。你可以把它想象成一本巨大的电话本,比如当你要访问域名www.baidu.com
时,就可以通过 DNS 查出它的 IP 地址是36.152.44.95
。
③ 端口号
服务器本质上一个进程,我们需要到这个进程下获取服务。一台主机下可以有多个不同进程,如果域名标识的是网络中具体的某台主机的话,端口号标识的就是主机中的进程,其值是一个16比特位的整数,范围:0 ~ 65535。
HTTP 协议的默认端口号是 80,如果不写的话,服务器检测到是 HTTP 协议,就会默认到端口号为 80 的进程中提供服务。在 URL 中,端口号紧跟在域名之后,两者之间使用冒号分隔,比如:www.baidu.com:80
下面是一些常见应用层协议及其它们的默认的端口号:
协议名 | 默认端口号 |
---|---|
HTTP | 80 |
HTTPS | 443 |
PPTP | 1723 |
④ 文件路径
文件路径指的是我们需要获取和访问的资源在对端主机中的具体位置。比如 path/index.html
这个路径,它的含义是到服务器主机的 path 子目录下面的网页文件 index.html。
有些时候,路径可能只包含目录,而不是指向具体的一个文件,比如 foo/ ,甚至结尾的斜杠都可以省略。这时,服务器通常会默认跳转到该目录里面的 index.html 文件(即等同于请求 foo/index.html 资源),但也可能有其他的处理(比如列出目录里面的所有文件),这取决于服务器的设置。一般来说,访问 www.example.com 这个网站,大部分返回的都是网页文件 www.example.com/index.html
说明:资源的文件路径在 URL 中,用反斜杠 /
与端口号分隔,例如 http://www.example.com:80/index.html
⑤ 查询参数
查询参数(parameter)是客户端提供给服务器的额外信息。这些参数通常跟在路径后面,使用?
分隔,查询参数通常以 key-value 键值对的形式存在,多个查询参数彼此之间用&
分隔,如:key1=value1&key2=value2。
查询参数的作用是用来给服务器提供额外的信息,比如我们在百度搜索栏中输入 csdn,跳转后去查看对应的 URL,发现有一组查询参数叫 wb=csdn,这个参数就是我们交给服务器的一个信息,服务器解析之后会给我们返回一系列 csdn 相关的资源:
3. URL中的字符
3.1 合法字符
在 URL 的各个组成部分中,只允许使用以下这些字符,我们称为合法字符:
- 26个英语字母(包括大写和小写)。
- 10个阿拉伯数字
- 连词号(-)
- 句点(.)
- 下划线(_)
3.2 保留字符
此外,还有18个字符属于 URL 的保留字符,它们只能在给定的位置出现。比如,查询参数的开头是问号(?),也就是说,问号只能出现查询参数的开头,出现在其他位置就是非法的,不然导致 URL 解析错误。URL 的其它部分如果想使用这些保留字符,就只能使用它们的转义形式。
针对保留字符的转义指的是在这些字符的十六进制 ASCII 码前面加上百分号(%)来标识原字符。
下面是这18个字符及其转义形式:
- !:%21
- #:%23
- $:%24
- &:%26
- ':%27
- (:%28
- ):%29
- *:%2A
- +:%2B
- ,:%2C
- /:%2F
- ::%3A
- ;:%3B
- =:%3D
- ?:%3F
- @:%40
- [:%5B
- ]:%5D
举例来说,一个路径资源的名称是 /foo?bar.html,即它的文件名里面包含一个问号,那么在 URL 中,就需要转义写成 foo%3Fbar.html
PS:URL 的合法字符,其实也可以采用这种转义方法,但是不建议使用。比如,字母a的十六进制 ASCII 码是61,转义形式后就是 %61。因此,www.apple.com又可以写成www.%61pple.com,浏览器一样可以识别 。
3.3 其他字符
对于 URL 而言,既不属于合法字符、也不属于保留字符的其他字符(比如汉字),理论上不需要手动转义,可以直接写在 URL 里面,比如 www.example.com/中国.html,浏览器会自动将它们转义,发给服务器。转义方法是使用这些字符的十六进制 UTF-8 编码,从右往左每两位算作一组,然后每组头部添加百分号(%)。
举例来说,‘中’这个字的 UTF-8 十六进制编码是 E4B8AD,从右往左每两个字符一组,URL 转义后就表示为%E4%B8%AD
。也就是说,URL 里面凡是有‘中’这个汉字的地方,都要写成 %e4%b8%ad。‘国’这个汉字是转义后是%E5%9B%BD
,因此,访问 www.example.com/中国.html 这个资源,最终在 URL 中会呈现为下面的样子:
www.example.com/%E4%B8%AD%E5%9B%BD.html
3.4 URL中的字符总结
URL 中字符的转义我们称为 urlencode,反转义的过程我们称为 urldecode,下面连接是一个工具,可以帮助我们在线进行 URL 转义和反转义:urlencode工具
二. HTTP 协议
1. HTTP 介绍
HTTP 即超文本传输协议(Hypertext Transfer Protocol)
-
超文本:在互联网早期的时候,我们输入的信息只能保存在本地,无法和其他电脑进行交互。我们保存的信息通常都以文本即简单字符串的形式存在,此时的文本是一种能够被计算机解析的有意义的二进制数据包。而随着互联网的高速发展,两台电脑之间能够进行数据的传输后,人们不满足只能在两台电脑之间传输文字,还想要传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转,这样文本的语义就被扩大了,这种语义扩大后的文本就被称为超文本(Hypertext)。
-
传输:那么我们上面说到,两台计算机之间会形成互联关系进行通信,我们存储的超文本会被统一地解析成为二进制数据包,然后由传输载体(例如同轴电缆,电话线,光缆)负责把这些二进制数据包由计算机终端传输到另一个终端的过程称为传(transfer)。
-
协议:协议就是网络中(包括互联网)传输、管理信息的一些规则规范。如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间的相互通信也需要共同遵守一致的规则,这些规则就称为网络协议(协议的理解)。
综上我们可以给 HTTP 做一个通俗的解释:HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范,它隶属于应用层。
HTTP 和 HTTPS 有什么区别?
HTTPS 是 HTTP 的加密版本,一直以来 HTTP 协议都是最主流的网页协议,HTTP 协议被用于在 Web 浏览器和网站服务器之间传递信息,以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文(抓包),就可以直接读懂其中的信息。
HTTPS 协议可以理解为 HTTP 协议的升级,就是在 HTTP 的基础上进行了数据加密,即在数据进行传输之前,对里面的数据进行加密,然后再发送给服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息仍然是安全的。这就是 HTTP 和 HTTPS 的最大区别。
比如跳转到支付宝官网,我们去查看它的 URL 发现用的是对数据进行加密的 HTTPS 协议,出于安全考虑,越来越多的网站使用这个协议。
HTTP 报文格式
HTTP 报文按照传输数据的性质划分,可以分为:请求报文和响应报文。
2. 请求报文
2.1 请求报文的格式
HTTP 的请求报文格式如下:
可以看到 HTTP 的请求报文主要由以下五个部分构成:
- 请求行: [请求方法] + [URL] + [HTTP版本]
- 请求报头:以键值对的形式按行陈列,存储请求报文的相关属性信息
- 空行:作为报头和请求正文之间的分隔符
- 请求正文:如果请求方法为 GET,那么请求正文为空。它主要是在 POST 这个请求方法中用到,一般用于提交表单或者上传文件
2.2 请求方法介绍
HTTP的请求方法共计有8种,它们的描述如下表所示:
方法 | 说明 |
---|---|
GET | 请求指定的页面信息,并返回实体主体。 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被放在有效载荷中。POST 请求可能会导致新资源的建立和/或已有资源的修改。 |
HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,它主要目的是用来获取报头。 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
DELETE | 请求服务器删除指定的页面。 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
OPTIONS | 允许客户端查看服务器的性能。 |
GET 方法的特点
通常我们向服务器发送请求报文时,可以传一些参数过去,如果请求方法是 GET 的话,我们输入的参数是保存在 URL 当中的,保存在 URL 当中,参数的私密性就不会太好,因为参数内容会在输入地址框中的 URL 中回显出来。
然后传送时,这些请求参数会被保存在请求行的 URL 之中,以问号作为分隔符,前半部分是访问资源的路径,后半部分就是我们的请求参数,多个参数之间用 & 连接。GET 方法的 URL 一般都具有长度限制,但是需要注意的是 HTTP 协议中并未规定 GET 的长度。这个长度限制主要是由浏览器和 Web 服务器所决定的,并且各个浏览器对长度的限制也各不相同。
POST 请求方法的特点
相比于 GET,POST 这种请求方式的私密性要更好(因为在输入时,请求参数不会直接在浏览器的输入地址框中回显),但它们其实都是不安全的。
POST 方法的请求参数是放置在请求正文中的,所以它的请求信息是没有长度限制的:
GET 和 POST 请求方法的区别
- GET 是获取数据,POST 是修改数据
- GET 把请求数据放到 URL 中、POST 把请求数据放到正文中,所以 POST 传参要比 GET 传参更私密一些
- GET 提交的数据最大是2K( 限制实际上取决于浏览器), POST 理论上没有限制
- 传输时 GET 产生一个 TCP 数据包,浏览器会把报头和有效载荷一并发送出去,服务器响应200(返回数据);而 POST 传输时产生两个 TCP 数据包,浏览器先发送报头,服务器响应 100 continue,浏览器再发送有效载荷,服务器响应 200 ok(返回数据)
补充:HEAD 请求方法
HEAD 请求与 GET 请求类似,只不过服务器发回的响应报文没有有效载荷。在一个基于 HEAD 请求的响应中,HTTP 头中包含的元信息应该和一个 GET 请求的响应报文头信息相同。这种方法可以用来获取请求中隐含的元信息,而不用传输实体本身,因此可以用来获取服务器上的资源的元数据,如资源的大小、类型、更新时间等,而不需要获取实际的数据内容。
2.3 请求报文中常见的 header
前面说过,在请求报文中存储着一个个按行陈列的 key/value 键值对,它们原来表示请求属性:
下面介绍一些常见的报头信息:
Content-Type
含义:表示请求中的 body 数据格式,由于 body 中的数据格式不同,对接受方来说解析方法截然不同
说明:HTTP 本来就是超文本传输协议,它可以在有效载荷中传输任意类型的数据(html、css、cs、图片、视频、音频等),此字段就是说明该 HTTP 报文所传输数据的类型。
Content-Length
含义:有效载荷(body)的长度
Host
含义:表示需要访问的服务器的目的 IP 地址和目的端口号
问题:那么既然 URL 里面也有服务器的 IP 地址和端口,为什么还要搞个 HOST 呢?事实上,URL 里面的 IP 地址和端口,和 HOST 中的不完全一样,比如当请求是通过代理来访问的时候,是可能不一样的
User-Agent
含义:声明用户的操作系统和浏览器的名称和版本信息
说明:该 header 的作用是用来告诉服务器, 客户端使用的操作系统和浏览器的名称和版本。比如我们去官网下载一个 app 时,往往会看到一些下载相关的信息,其中列出了你的操作系统的名称和版本和你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从你发过来的请求报文中的 User-Agent 中获取到这些信息的。
referer
含义:当前页面是从哪个页面跳转过来的
说明:当浏览器向 web 服务器发送请求的时候,一般会带上 Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理一些操作,比如返回上一级:
location
含义:搭配 3xx 状态码使用, 告诉客户端接下来要去哪里访问
示例:
Cookie
含义: 用于在客户端中存储少量信息,通常用于实现会话(session)功能
示例:有些网站,我们输入账号密码登陆过一次,之后再访问这个网站时,客户端会帮我们自动登录好,这是为什么呢?按理来说,HTTP 是一种无状态的协议,每个报文之间是没有任何关联的,比如在爱奇艺中看电视剧,每打开一个网页,就应该重新输入账号密码来访问的,但是实际并没有,这是怎么做到的呢?
这其实就是通过 Cookie 来实现的,比如我当前在 CSDN 中,就能找到它相关的 Cookie 数据:
具体实现原理如下:
Cookie 信息既然是一个 header 放在请求报文中,那传输过程中,Cookie 文件可能会被恶意用户盗取,然后他们就可以登录我们的账号来进行恶意操作。
针对如上情况,一般通过如下三种策略来保证我们账户的安全:
- 如果恶意用户盗取并使用 Cookie 文件对你的账户进行了远程异地登录,那么服务器会检测到这次异地登陆然后在自己的 session_id 集合中清除这个异地登陆的 session_id,并提醒你:“检测到你的账户远程异地登录了,可能存在风险”这时你想访问的话只能你自己重新输入账号密码,然后服务器那边再重新给你生成新的 Cookie 文件存储到你的客户端中,那么之前那个被盗 Cookie 文件的 session_id 也就没用了
- 即使不是异地登录,那些骗子只能拿到你的 Cookie 文件并登录了你的账号,如果他们想改你密码也是不行的,因为这时服务器会要求你进行密码验证,而这是只能拿到 sesssion_id 的骗子无法做到的
- 此外,有些服务器对 session_id 的管理是时效性的,即一段时间后会清除过期的 session_id,此时要再次访问的话必须重新输入账号密码,然后更新 session_id
3. 响应报文
3.1 响应报文的格式
服务端在收到请求后一般要根据请求内容去进行一些操作,完成后以响应报文的形式发回给客户端。
- 状态行: [版本号] + [状态码] + [状态码描述]
- 响应报头:以(key:value)键值对的形式存在,最后读到空行时代表报头部分结束。
- 空行:作为报头和响应正文之间的分隔符
- 响应正文:空行后面的内容都是响应正文,该部分允许为空字符串;如果它存在, 则在响应报头中会有一个 Content-Length 的关键字来标识正文的长度; 如果服务端返回了一个 html 页面,那么 html 页面内容就是在正文中。
3.2. 常见状态码及状态码描述
状态码 | 类别 | 意义 |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
1xx 信息
- 100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。
2xx 成功
- 200 OK,请求正常处理完毕
- 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
- 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。
3xx 重定向
- 301 Moved Permanently :永久性重定向
- 302 Found :临时性重定向
- 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
- 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。
- 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。
补充:临时、永久重定向
-
临时重定向:浏览器不会缓存当前域名的解析记录
-
永久重定向:浏览器会缓存永久重定向的 DNS 解析记录。即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器
本质区别:影响客户端标签,决定客户端是否需要更新目标地址
4xx 客户端错误
- 400 Bad Request :请求报文中存在语法错误。
- 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。
- 403 Forbidden :请求被拒绝。
- 404 Not Found
5xx 服务器错误
- 500 Internal Server Error :服务器正在执行请求时发生错误。
- 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。