HTTP 协议

HTTP 协议_第1张图片

目录

​编辑一、HTTP 协议是什么

二、抓包工具的使用

三、HTTP 请求

1、认识 URL

2、认识方法

3、认识请求 “报头”

HOST :

Content-Length 和 Content-Type​编辑

User-Agent

Referer

四、HTTP 响应

1、认识状态码 

2、通过 form 表单构造 HTTP 请求

3、通过 ajax 构造 HTTP 请求

4、使用第三方工具构造 HTTP 请求

 五、HTTPS

1、认识HTTPS

2、加密

3、证书


一、HTTP 协议是什么

 HTTP 属于是应用层最广泛使用的协议之一

浏览器获取到网页就是基于 HTTP

所以我们可以认为:HTTP 就是 浏览器 和 服务器 之间的交互桥梁

HTTP 协议_第2张图片

当我们在浏览器中搜索网址的时候,这个东西更准确的说,叫做 URL

浏览器就会根据这个 URL ,构造出一个 HTTP 请求,发送给服务器,服务器就会返回一个 HTTP 响应(包含了 html ,css ,js,图片)

浏览器再把得到的 html 数据进行显示出来(渲染)


二、抓包工具的使用

HTTP 协议的交互详细过程,是可以借助第三方的工具来看到的,称为 “抓包” 工具

抓包工具有很多,我这里使用的是 fiddler

当我们打开 fiddler 之后,它就会立即显示出当前电脑上某个程序使用 http 和服务器交互的过程

HTTP 协议_第3张图片

fiddle 本质上是一个代理程序,使用的时候有两个注意事项:

1、可能和别的代理程序冲突,使用的时候要关闭其它的代理程序(包括一些浏览器插件)

2、要想正确抓包,还需开启 https 功能

代理分两种:正向代理和反向代理

代表客户端的代理叫做正向代理

代表服务器的代理叫做反向代理

https 是基于 http 搞出来的进化版协议

当下互联网上绝大部分的服务器都是 https ,fiddler 默认不能抓 https 的包,需要我们手动启用一下 https 并安装证书

HTTP 协议_第4张图片

把这几个复选框都给勾上, fiddler 才能抓取 https ,首次勾选的时候,会弹出一个对话框,问你是否要安装对应的证书(英文) ,这个时候要选择 “是”

当我们再重新打开一个页面的时候,就可以看到产生的 http 请求

浏览器打开一个页面,对应的 HTTP 请求可能是一个,也可能是多个

HTTP 协议_第5张图片

其中,这个就是我们最关注的一条,再请求 百度 的首页页面的时候,其它的请求都是基于这个请求产生的(百度主页里,其他代码又产生了别的请求) 

双击左侧请求列表中的选项,就能看到请求中的详细情况

HTTP 协议_第6张图片

http 请求,是有一定的格式的,fiddler 会按照格式解析,呈现出不同的显示效果,此处就看最原始的效果(raw)

观察抓包结果,可以看到,当前 http 请求,其实是个 行文本 格式的数据

HTTP 协议_第7张图片

行文本 的格式,相比于 tcp 这种二进制格式来说,就更方便用户直接观察

响应数据本来也是文本的,但是有的服务器会对响应进行压缩(变成二进制了),压缩式为了节省带宽 

HTTP 协议_第8张图片

 有了以上的认知之后,我们就可以来了解一下 http 里面一些关键信息的含义了


三、HTTP 请求

我们点开响应内容: 

首行,包括三个部分,之间使用 空格 来区分

GET : HTTP 的方法(method)

URL :俗称的网址,叫做唯一资源定位符

HTTP/1.1 :版本号

URL 叫做唯一资源定位符,标识互联网上的唯一的资源的位置,描述资源在哪(在哪个服务器的哪个目录下的哪个文件中)

还有一个 和 URL 名字类似的东西:

URI:唯一资源标识符(身份标识,为了和别的资源分别开)

实际上,URL 也可以起到身份标识的效果,URL 也可以视为是一个 URI 


1、认识 URL

先来看一下 URL 的协议格式: 

HTTP 协议_第9张图片

URL 的协议格式,是由 rfc 系列文档定义的

tcp ,ip ,udp 协议格式都是 rfc 系列文档定义的

URL 不是 http 专属的,很多协议都可以使用 URL 

HTTP 协议_第10张图片

 URL 的最关键的四个部分:

1、域名 / IP 地址

2、端口号

3、带层次的路径

4、查询字符串(以键值对的方式来组织的)

一个 URL ,这里的几个部分,有些是可以省略的!!!

比如这个,省略了端口,省略端口的时候,浏览器会提供默认端口

对于 http 来说,默认端口是 80,对于 https 来说,默认端口是 443

/ 也是路径,没有省略,只是有点短,代表 “根目录”

这里的 “根目录” 指的是 HTTP 服务器的根目录

HTTP 服务器是系统上的一个进程,就委托这个服务管理系统上的一个特定的目录,这个目录里的资源都可以让外面去访问

HTTP 协议 和 HTTP 服务器 之间是什么关系?

HTTP 协议_第11张图片

一个 HTTP 服务器 提供的资源是很多的,不同的路径,拿到的是不同的服务器

HTTP 协议_第12张图片

但是正常情况下,是这个样子的: 

HTTP 协议_第13张图片

这个 URL 里,就带有 query string 

query string 是以 ?开头,以键值对的方式组织,键值对之间使用 & 分割,键和值之间使用 = 分割

URL 里面有些字符是有特定含义的,所以就需要对内容进行重新编码(urlencode),如果不编码,直接写中文,浏览器可能就没办法正确识别了


2、认识方法

方法描述了这次请求的语义(想干什么) 

HTTP 协议_第14张图片

实际开发中,这里的方法大部分都是用不到的,最常见的就是两个:GET ,POST

此处看到的 HTTP 的方法的语义,是 HTTP 设计者的美好的想法,但是实际上,开发的时候,语义仅供参考 


触发 GET 请求的方式:

1、在浏览器的地址栏里直接输入 URL 

2、html 里的 link ,script,img,a....

3、通过 js 来构造 GET 请求

HTTP 协议_第15张图片

 第一行,称为 “首行”,剩下来的被圈起来的部分叫做 “header” 部分

POST 典型的就是登录

登录跳转的时候会涉及到 POST,另一种典型情况就是上传文件

当然也有其它触发 POST 请求的情况,但是这两种更为典型

HTTP 请求可以分成是四个部分:

1、首行

2、请求头(header)

3、空行

4、正文(body)

如果是 GET 请求,没有 body

如果是 POST 请求,一般有 body

在抓包结果中,我们可以看到,post 的结果是程序员自定义的内容

其中,uuid 指唯一身份标识:可以通过一定的算法,构造出这样的一个长字符串,每次构造的长字符串都是不同的

这里存放的数据的内容和格式,都是程序员自主定义的

GET 和 POST 之间的典型区别: 

(1)GET 也可以给服务器传递一些信息,只不过 GET 传递的信息一般都是放在query string ;而POST 传递信息则是通过 body

(2)GET 请求一般是用于从服务器获取数据,POST 一般是用于从服务器提交数据(语义上的差别)

(3)GET 通常会被设计成幂等的,而 POST 不要求幂等

(4)GET 可以被缓存;而POST 一般不能被缓存

注意:这里的区别只是一个习惯用法,GET 也不是不能有 body ,POST 也不是不能有 query string,只是非常少见

GET 和 POST 其实没有本质区别(在大部分场景下,彼此之间都能够互相替代)

但是在使用习惯上,还是有差异的

幂等可以理解成:相同的输入,得到的结果也是相同的

缓存指的是:把请求的结果保存下来了,下次请求就不必真请求了,直接取缓存结果了

所以,缓存的前提是幂等


3、认识请求 “报头”

下列部分,就是 header 部分,这里是一堆键值对!

HTTP 协议_第16张图片

每一行,是一个键值对,每一个键值对之间用 ; 分割

这些键值对都是 HTTP 事先定义好的,有特定含义的

比如:

HOST :

大概描述了服务器大概所在的地址和端口

HOST 这里的 地址 和 端口,用来描述你最终要访问的目标

也就是说,这里的内容,大概率和 URL 中是一样的 ,也有不一样的情况


Content-Length 和 Content-Type

 Content-Length :表示 body 中数据的长度

Content-Type :表示请求的 body 中数据的格式

如果是 GET 请求,没有 body,请求中没有这两个字段

如果是 POST 请求,有 body,请求中必须有这两个字段


User-Agent

主要描述了当前 浏览器 和 操作系统 的版本

最早期的浏览器,只支持文本,后来支持图片,再后来支持视频,音频.....

网站开发者在开发的时候,做的网页是否要带图片,视频之类的,就很难抉择

于是干脆分成了多个版本,针对不同的浏览器做多个版本,判定请求的 user-agent,根据这个不同的类别,返回不同的版本内容

现在,User-Agent 主要用来区分 PC 和 移动


Referer

表示当前页面的 “来源”

如果直接通过地址栏输入地址,直接点击收藏夹....都是没有 referer

我们浏览网页的时候,会发现网页上常常会有广告,广告主按照广告的点击量给广告平台发钱,广告被点击了多少次?次数如何衡量?这些次数是由广告商和广告平台一起统计的,如果统计的数据对上了,那么就没有问题,如果数据没有对上,那么程序员就要去查问题的原因

但是一个广告也可能被投放在了多个平台上,那么就是用 referer 来分辨广告是在哪个网页上被点击的

HTTP 本身是明文传输,意味着很容易能够获取到请求内容,也有办法篡改内容

那么有没有可能本来是来自搜狗的请求,但是 referer 被改成了别人的呢?

referer 是 HTTP 层面的东西,交换机和路由器正常情况下,是不会干涉的,但是有时候运营商为了钱,可能会出现篡改数据的情况


Cookie 是一个非常重要的 header 属性

本质上是 浏览器 给 网页 提供的 本地存储数据 的机制

网页,默认是不允许访问你计算机的硬盘的(安全)

Cookie 就相当于是 浏览器对于访问硬盘做出了明确的限制

Cookie 就是通过键值对的方式来组织数据的

至于 Cookie 中具体存的内容是什么,也就是程序员自定义的部分

Cookie 是从哪来的?

Cookie 中的数据,是来自于服务器的

服务器会通过 HTTP 响应的报头部分(Set-Cookie字段)

服务器来决定,浏览器的 Cookie 要存什么

Cookie是存在哪的?

可以认为是存在于浏览器中,存在于硬盘的

Cookie 在存的时候,是按照 浏览器 + 域名 维度来进行细分的

不同的浏览器,各自存各自的Cookie 

同一个浏览器,不同的域名,对应不同的Cookie

Cookie 里面的内容,不光是键值对,同时还有过期时间

Cookie 要到哪里去?

回到服务器去

客户端同一时间是有很多的

客户端这边就会通过 Cookie 来保存当前用户使用的中间状态,当客户端访问浏览器的时候,就会自动的把 Cookie 的内容带入到请求中,服务器就知道现在客户端时什么样的了


四、HTTP 响应

1、认识状态码 

响应也是由四个部分构成:

1、首行

2、header 

3、空白行,表示 header 的结束标记

4、body

HTTP 的状态码,描述了这次响应的结果

HTTP 协议_第17张图片

200 :OK成功了

404 : Not Found,访问的资源不存在

403 : Forbidden ,访问被拒绝(没有权限)

302:Move Temporanly 重定向(类似呼叫转移)

500:服务器内部错误(服务器代码抛异常)

504 : getway timeout(响应时间太久)

重定向和请求转发的区别:

重定向:

HTTP 协议_第18张图片

 请求转发:

HTTP 协议_第19张图片

重定向,可以重定向到外部资源(跳转到别的网站)

请求转发只能该服务器内部的资源之间转发,少了一次交互,更高效

这么多的状态码,其实是可以分为几个大类的:

HTTP 协议_第20张图片

HTTP 协议里面,有不少地方,是可以由程序员自定义的:

1、URL 中的路径

2、URL 中的 query string

3、header 中的键值对

4、header 中的 Cookie 键值对

5、body


HTTP 的报文协议格式

HTTP 协议_第21张图片


2、通过 form 表单构造 HTTP 请求

对于 GET 

1、地址栏直接输入

2、点击收藏夹

3、html 中 的 link ,script,img,a.....

4、通过 form 标签




    
    
    Document


    
    
    

我们打开这个网页,然后输入 "zhangsan" 后,在 fiddler 中观察HTTP 的请求

HTTP 协议_第22张图片

除了首行之外,剩余部分都是浏览器自主添加的

可以看到,我们构造的这个请求,搜狗的服务器没有做什么特殊的处理,仍然是噗噗通通的返回搜狗主页了

我们后续写服务器代码,就可以根据需求,来获取 URL 中的 query string ,从而完成不同的功能

对于 form 构造的 POST 请求来说,body 里面的数据格式,就和 query string 是非常相似的,也是键值对结构,键值对之间通过 & 分割,键和值之间使用 = 分割

form 标签,只能构造 GET 和 POST ,无法构造 PUT ,DELETE 等


3、通过 ajax 构造 HTTP 请求

ajax 也是浏览器提供的一种,通过 js 构造 HTTP 请求的方式

a 指的是 asynchronize,异步的意思

同步:A 始终盯着 B,A 负责关注 B 啥时候就绪

异步:A 不盯着 B,B 就绪后主动通知 A

html 中,通过 ajax 发起 HTTP 请求,就属于是 “异步” 的方式

这一行代码执行 “发送请求” 操作之后,不必等待服务器响应回来,就可以立即先往下执行,当服务器的响应回来了之后,再由浏览器通知到咱们的代码中

代码中如何使用 ajax?

1、js 原生提供的 ajax 的 api,但是原生的 api 很难用

2、jquery 提供的 ajax ,api 针对原生 api 的封装,简单很多

我们这里选择更简单的第二种写法

jquery 中,$ 是一个特殊的全局对象

jquery 的 api 都是以 $ 的方法的形式来引出的

ajax 这个方法的参数,只有一个参数,是一个 js 对象(大括号表示的键值对)




    
    
    Document


    
    
    

注意:该代码直接执行,只是能看到构造的请求,无法获取到正确的响应

因为发送请求给搜狗服务器,人家的服务器没有处理我们的请求

请求构造的顺序是从上到下的,但是收到响应的顺序/触发回调的顺序是不确定的(网络上可能会后发先至)

等到后面我们自己编写服务器的时候,就可以给自己的服务器发送请求,自然就能够处理了

和 form 相比,ajax 功能更强

1、支持 put,deelte 等方法

2、ajax 发送的请求可以灵活设置 header 

3、ajax 发送的请求的 body 也是可以灵活设置的


4、使用第三方工具构造 HTTP 请求

我们可以使用 postman 进行构造 HTTP 请求

1、先注册登录

2、创建一个 workspace

3、新建一个标签页

HTTP 协议_第23张图片

除了刚才手动构造之外,postman 还有一个很强的功能:

postman 可以生成构造请求的的代码,方便我们在自己的程序中集成

HTTP 协议_第24张图片


 五、HTTPS

1、认识HTTPS

HTTPS :HTTP + 安全层(SSL)

SSL:用来加密的协议

网络上如果明文传输数据,是非常危险的,需要加密才能保证安全

HTTPS 其实主要涉及到的是其中的 SSL 部分

SSL 并非仅仅是在 HTTPS 中使用


2、加密

进行安全传输的核心就是加密

加密其中一种最简单有效的办法叫做 “对称加密”

a(明文) + key => b(密文)——加密的过程

b(密文) + key => a(明文)——解密的过程

同一个密钥,既可以用来加密,也可以用来解密,就称为对称密钥

对称加密的安全性的前提就是密钥不能被黑客知道

密钥就可以认为是一串 数字 / 字符串

加密的过程,就可以理解为把明文和字符串进行一些列的数学变换(其中最简单的一种方式就是 ^)

HTTP 协议_第25张图片

由于黑客不知道密钥是什么 ,即使黑客截获了加密的数据,也不知道这里是什么意思

客户端生成密钥还是服务器生成密钥?

由于一个服务器对应很多个客户端,这些客户端每个人都有不同的密钥

假设客户端生成一个密钥,客户端就需要把密钥告知服务器

HTTP 协议_第26张图片

客户端生成密钥,发给服务器,此时由于密钥刚刚生成,此处的密钥只能明文传输,密钥就可能被黑客给截获了

以上问题,关键在于需要想办法把密钥传递过去,因此还得加密

此处,我们可以引入非对称加密

生成一对密钥:公钥和私钥

明文 + 公钥 => 密文——使用公钥加密

密文 + 私钥 =>明文——使用私钥解密

公钥可以公开,私钥是私藏的

HTTP 协议_第27张图片

服务器生成一对公钥私钥,其中客户端持有公钥,服务器持有私钥

此时,客户端的公钥从服务器拿,黑客也能知道公钥,但是黑客不知道私钥,因为私钥是服务器自己持有的

客户端使用公钥对对称密钥进行加密,传输给服务器,服务器就可以拿着自己的私钥来解密得到对称密钥

此时客户端服务器就可以使用这个对称密钥进行后续传输了

为什么有了非对称加密,还要继续保留对称加密呢?

对称加密速度快,非对称加密速度慢

使用对称加密是为了尽可能提高整体的速度


3、证书

但是问题来了,有时候黑客会模仿服务器给客户端发送密钥,也就是中间人攻击

HTTP 协议_第28张图片

中间人攻击的要点在于,客户端不知道响应式来自于真实的服务器还是黑客的

解决中间人问题的关键在于,让客户端能够辨别当前这个响应(公钥)是服务器真实的公钥

于是,我们引入了 “证书”(本质上是引入了第三方的公证机构)

服务器(网站)在设立之初,就需要去专门的认证机构,申请证书(提供一些资质)

审核通过,就会给你颁发证书,服务器生成的公钥也就包含在这个证书中

客户端向服务器请求公钥的时候,就不单单是请求一个公钥,而是把整个证书都请求过去了

客户端拿到证书之后,就可以对证书进行校验(验证一下证书是不是假的,是不是被篡改的)

如果发现证书是无效的,浏览器就会直接弹窗告警

HTTP 协议_第29张图片

客户端拿到证书,就可以对证书进行一个校验

证书上面会带有一个特定的字段,叫做证书的签名,客户端可以通过证书的签名看它是不是有效的证书

签名就是一个被加密的字符串

客户端就可以使用认证机构提供的公钥进行解密,解密之后得到的结果,相当于是一个 hash 值

类似于 tcp 和 udp 里面的校验和,根据证书的其它字段,综合计算出来的结果

客户端就可以使用同样的 hash 算法,针对其它的字段再计算一次 hash值,得到 hash2

看看 hash1(从签名中解出来的)和 hash2(客户端自己算的),如果这两个值相同,就说明证书是有效的(没有被篡改过)

黑客能否把证书给篡改了?

一旦替换了公钥,意味着客户端算的 hash2 和签名解密出阿里的 hash1 就对不上了,客户端就知道无效

另一方面,黑客不知道认证机构的私钥,即使黑客自己算好了新的篡改之后的 hash 值,也无法加密生成签名

认证机构也有一组公钥和私钥,私钥用来加密 hash 值 得到签名,公钥是客户端拥有的使用公钥解密签名获取 hash

你可能感兴趣的:(Java,EE,http,网络协议,网络,https,java-ee,缓存)