详解HTTP协议和HTTPS协议

目录

一.HTTP协议

1.什么是HTTP

 2.HTTP发展历史

3.HTTP请求和响应

4. 抓包的方式和工具Fiddler

1.开发者工具

 2.Fiddler

 二.请求和响应

1.请求和响应报文

扫描二维码关注公众号,回复: 15428601 查看本文章

 2.URL结构

 3.常见的方法

1.GET方法

2.POST方法

 3.其他方法

 三.请求报头(header)

1.Host

2.Content-Length

3.Content-Type

4.User-Agent(UA) 

5.Referer

6.Cookie

四.响应详解(Response)

1.常见的状态码

1.200 OK

 2.响应 "报头" (header)

五.发送POST和GET请求

1.通过form表单构建HTTP 请求

1.GET

2.POST

2.通过ajax构建HTTP 请求

1.GET

2.POST

六.HTTPS

1.什么是HTTPS

2.SSL/TLS协议

3.为什么会出现HTTPS

4.加密和常见的加密方式

1.对称加密

2.非对称加密

3.哈希函数

5.什么是证书

6.HTTPS的工作流程

1.引入对称加密

2.引入非对称加密

3.引入证书

4.完整流程


一.HTTP协议

1.什么是HTTP

HTTP ( 全称为 " 超文本传输协议",英文Hyper Text Transfer Protocol ) 是一种应用非常广泛的 应用层协议.
超文本的解释:所谓超文本指的是传输的内容不止是文本内容(html,css),还可能是一些其它资源,如音频,图片,视频等

HTTP是基于TCP协议的一种应用层协议,无论是哪个应用实现实现(不一定非要浏览器),只要按协议规定的格式完成数据的编码与解析
编码完成后通过socket api发送出去,接收到数据之后再按规定的格式去解析就可以了

常见的应用场景:

  • 浏览器和服务器之间通信
  • 手机与服务器之间通信
  • 多个服务器之间进行调用(请求转发)

 2.HTTP发展历史

HTTP 往往是基于传输层的 TCP 协议实现的 . (HTTP1.0, HTTP1.1, HTTP2.0 均为 TCP, HTTP3 基于 UDP实现 )
目前我们主要使用的还是 HTTP1.1 和 HTTP2.0 . 本文主要以HTTP 以 1.1 版本为主 .

3.HTTP请求和响应

当我们在浏览器中输入URL(例如www.baidu.com),根据域名通过DNS解析成ip地址,给TCP/IP发送给服务器HTTP请求(request),服务器接收到请求之后,分析用户需要访问哪些资源,然后将所需的资源响应(response)给浏览器,浏览器解析响应的数据,渲染到页面上.

当发送请求和接收响应的时候,我们该如何查看请求的具体信息和响应的具体信息呢?

4. 抓包的方式和工具Fiddler

1.开发者工具

无论在哪一个浏览器,我们按键盘上的F12(可以按Fn+Esc开启FnLock)的时候,就可以打开开发者工具,里面的Network(或者网络)就是访问网站的具体请求和响应信息

FireFox访问百度页面

Google Chrome访问百度页面

 2.Fiddler

可以通过官网Fiddler来进行下载抓包工具,下载Fiddler Classic版本即可

 请求报文的信息在记事本查看

Fiddler工作原理

当浏览器发送请求到服务器的时候,Fiddler在浏览器发送请求之后先拿到请求,然后Fiddler再把请求发送给服务器,服务器发送响应的时候,Fiddler先接受到响应,然后再将响应发送给浏览器.

 二.请求和响应

1.请求和响应报文

下面是具体的请求和响应报文的大致结构

 2.URL结构

 URL:(Uniform Resource Locator 统一资源定位符)

URI:(Uniform Resource Identifier 统一资源标识符),一般在使用时候理解为同一个意思

下面是一个常见的URL地址

  • https : 协议方案名. 常见的有 http https, 也有其他的类型. (例如访问 mysql 时用的 jdbc:mysql )
  • user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
  • www.javacn.site: 服务器地址. 此处是一个 "域名", 域名会通过 DNS 系统解析成一个具体的 IP 地址. (通过 ping 命令可以看到, www.javacn.site 的真实 IP 地址为 82.157.146.10)                          可直接访问上面的网站
  • 端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
  • /interview/net/tcpip.html: 带层次的文件路径.
  • userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使 & 分隔. 键和值之间使用 = 分隔.
  • 片段标识: URL 中省略了片段标识. 片段标识主要用于页面内跳转.

 比如一篇文章的内容很长,用片段标识就可以很容易的定位到文章的某一个位置

URL 中的可省略部分
协议名 : 可以省略 , 省略后默认为 http://
ip 地址 / 域名 : HTML 中可以省略 ( 比如 img, link, script, a 标签的 src 或者 href 属性 ).
略后表示服务器的 ip / 域名与当前 HTML 所属的 ip / 域名一致 .
端口号 : 可以省略 . 省略后如果是 http 协议 , 端口号自动设为 80; 如果是 https 协议 , 端口号自
动设为 443.
带层次的文件路径 : 可以省略 . 省略后相当于 / . 有些服务器会在发现 / 路径的时候自动访问
/index.html
查询字符串 : 可以省略
片段标识 : 可以省略
关于query string

?后面跟着查询字符串,也是以键值对的形式来表示的,key=value如果有多个键值对要用&分隔
key=value&key1=value1&key2=value2

关于 URL encode
有一些特殊的字符(如'/',':')已经被使用,因此这些字符不能随意出现了,但是我们还需要使用一些特殊的字符,或者汉字,这个时候就需要先对特殊的字符进行转义.
转义的规则如下 : 将需要转码的字符转为 16 进制,然后从右到左,取 4 ( 不足 4 位直接处理 ) ,每 2 位做一位,前面加上 % ,编码成 %XY 格式
下面我们在百度中搜索:爱情,可以看出wd=%E7%88%B1%E6%83%85,爱情转义成为wd后面的十六进制串,同时我们可以使用开发者工具中的控制台,使用encodeURI进行转义,通过decodeURI进行反转义.

 3.常见的方法

请求的首行为:请求的方法,请求的地址,版本号

1.GET方法

1.如何发送一个GET请求

  1. 直接从浏览器输入URL地址,浏览器就会默认发送一个GET请求
  2. 通过form表单指定提交的方法为GET
  3. 通过AJAX方式发送一个GET请求
  4. HTML中的link,img,script等标签,也会触发GET请求.

2.GET请求的特点

  • 首行的第一部分为GET
  • URL的query string可以为空,也可以不为空
  • header部分有若干个键值对结构.
  • body部分为空.
关于 GET 请求的 URL 长度问题
网上有些资料上描述 : get 请求长度最多 1024kb 这样的说法是错误的 .
HTTP 协议由 RFC 2616 标准定义 , 标准原文中明确说明 : "Hypertext Transfer Protocol --
HTTP/1.1," does not specify any requirement for URL length.
没有对 URL 的长度有任何的限制 .
实际 URL 的长度取决于浏览器的实现 HTTP 服务器端的实现 . 在浏览器端 , 不同的浏览器最大长度是不同的 , 但是现代浏览器支持的长度一般都很长 ; 在服务器端 , 一般这个长度是可以配置的 .

2.POST方法

1.如何发送一个POST请求

  1. 通过form表单method=post
  2. AJAX方式指定method=post;

2.POST请求的特点

通过gitee进行登录操作的post请求

  • 首行的第一部分为 POST
  • URL query string 一般为空 (也可以不为空)
  • header 部分有若干个键值对结构.
  • body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由 header 中的 Content-Length 指定.

header和body之间空行的作用,为了解决粘包问题

 面试题:谈谈GET和POST的区别

  • 首先从总体上说,GET和POST本质上没有本质区别,两种方法都可以相互代替
  • 语义不同:GET一般用于获取数据,POST一般用于提交数据.
  • 使用习惯: GET的body一般为空,需要传递的数据通过query string 传递, POST的query string一般为空,需要传递的数据通过body传递
  • GET请求一般是幂等的, POST请求一般是不幂等的.(如果多次请求得到的结果一样,就视为请求是幂等的)
  • GET可以被缓存,POST不能被缓存.(因为GET请求是幂等的(得到的结果是一样的),因此进行缓存更加节省带宽资源,加快访问速度)

 3.其他方法

  • PUT POST 相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用

 三.请求报头(header)

1.Host

表示服务器的主机地址和端口

域名最终会被DNS服务器解析为IP地址,端口号确定与服务器对应的进程

2.Content-Length

表示 body中的数据长度
可以根据长度判断报文终止位置,一般不用我们手动指定,浏览器和服务器自己会计算好并赋值

如上面表示的body的长度为469个字节

3.Content-Type

表示请求的 body 中的数据格式 .
常见选项 :
1.application/x-www-form-urlencoded: form
表单提交的数据格式 . 此时 body 的格式形如 :

2.multipart/form-data: form 表单提交的数据格式 ( form 标签中加上 enctyped="multipart/form - data" . 通常用于提交图片 / 文件 .

3.application/json: 数据为 json 格式 .
body 格式形如

Content-Type主要用来标记客户端与服务器之间传输数据的类型,以方便服务器和客户端解析传输的数据.

4.User-Agent(UA) 

表示浏览器/操作系统的属性

使用UA可以让服务器收集客户端的环境,或是浏览器/操作系统的环境.

可以根据用户的浏览器和系统版,返回适合于当前用户的页面老的浏览器或系统,返回一些功能少的适合于老系统的页面,反之,比较新的浏览器或系统,就返回功能比较新的页面

5.Referer

记录是从哪一个URL跳转到当前页面的.

这个表示从gitee主页跳转到我本人的主页. .

实际案例:商城向其他平台投放广告,通过Referer信息来统计用户是从哪些平台点击进入到商城的,这样可以确定之后在哪个平台投放广告的效益最高.

6.Cookie

一个场景:

我们知道当我们访问网站(登录校验)的时候都需要进行用户的登录,当我们第一次登录了之后,我们可以访问响应的网站,但此时我们需要访问此站点的另一个网站,此时也是需要进行登录校验的,这个时候如果还是用户发送登录请求,这样用户的体验是很差的,因为刚才已经登录过了.那么我们该如何解决这个问题呢?接下来Cookie登场.

Cookie 中存储了一个字符串 , 这个数据可能是客户端 (网页)自行通过 JS 写入的 , 也可能来自于服务器 ( 服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据 ).
这些都是实现在浏览器保存简单数据的方式
前边的几个都比较新,使用的不多,Cookies比较久,使用的多

登录案例进行举例:

当我们第一次进行登录的时候,客户端发送请求,将登录的账号和密码发送给服务端,服务端进行账号和密码的验证,如果正确,登陆成功,此时会发送一个登录成功的响应

第一次登录的响应信息

HTTP/1.1 302 Found
Date: Thu, 10 Jun 2021 04:15:58 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=60
Server: nginx
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
Expires: Sun, 1 Jan 2000 01:00:00 GMT
Pragma: must-revalidate, no-cache, private
Location: https://gitee.com/HGtz2222
Cache-Control: no-cache
Set-Cookie: oschina_new_user=false; path=/; expires=Mon, 10 Jun 2041 04:16:00
-0000
Set-Cookie: gitee_user=true; path=/
Set-Cookie: gitee-session
n=M1Rhbk1QUUxQdWk1VEZVQ1BvZXYybG13ZUJFNGR1V0pSYTZyTllEa21pVHlBUE5QU2Qwdk44NXdEam
11T3FZYXFidGNYaFJxcTVDRE1xU05GUXN0ek1Uc08reXRTay9ueTV3OGl5bTdzVGJjU1lUbTJ4bTUvN1
l3RFl4N2hNQmI1SEZpdmVJWStETlJrdWtyU0lDckhvSGJHc3NEZDFWdHc5cjdHaGVtNThNcEVOeFZlaH
c0WVY5NGUzWjc2cjdOcCtSdVJ0VndzdVNxb3dHK1hPSDBDSFB6WlZDc3prUVZ2RVJyTnpTb1c4aFg1Mm
UxM1YvQTFkb1EwaU4zT3hJcmRrS3dxVFZJNXoxaVJwa1liMlplbWR5QXQxY0lvUDNic1hxN2o0WDg1Wk
E9LS10N0VIYXg4Vm5xdllHVzdxa0VlUEp3PT0%3D-
-2f6a24f8d33929fe88ed19d4dea495fbb40ebed6; domain=.gitee.com; path=/; HttpOnly
X-Request-Id: 77f12d095edc98fab27d040a861f63b1
X-Runtime: 0.166621
Content-Length: 92

可以看到响应中的set-cookie方法,在客户端中进行了cookie的设置,此后每一次向服务端发送请求的时候,都会将cookie放在请求头中发送出去,这样服务端进行cookie的校验,如果合理就不需要重新登录(表示之前已经登录过了),然后将相应的响应传送给前端

访问其他网站的请求信息

GET https://gitee.com/HGtz2222 HTTP/1.1
Host: gitee.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/91.0.4472.101 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,imag
e/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
Referer: https://gitee.com/login
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: oschina_new_user=false; user_locale=zh-CN; yp_riddler_id=1ce4a551-a160-
4358-aa73-472762c79dc0; visit-gitee--2021-05-06%2010%3A12%3A24%20%2B0800=1;
sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22726826%22%2C%22first_id%22%3
A%22175869ba5888b6-0ea2311dc53295-303464-2073600-
175869ba5899ac%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E
7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%
9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%2
4latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22175869ba5888b6-
0ea2311dc53295-303464-2073600-175869ba5899ac%22%7D; remote_way=svn;
tz=Asia%2FShanghai;
Hm_lvt_24f17767262929947cc3631f99bfd274=1622637014,1622712683,1622863899,1623298
442; Hm_lpvt_24f17767262929947cc3631f99bfd274=1623298550; gitee_user=true;
gitee-session
n=M1Rhbk1QUUxQdWk1VEZVQ1BvZXYybG13ZUJFNGR1V0pSYTZyTllEa21pVHlBUE5QU2Qwdk44NXdEam
11T3FZYXFidGNYaFJxcTVDRE1xU05GUXN0ek1Uc08reXRTay9ueTV3OGl5bTdzVGJjU1lUbTJ4bTUvN1
l3RFl4N2hNQmI1SEZpdmVJWStETlJrdWtyU0lDckhvSGJHc3NEZDFWdHc5cjdHaGVtNThNcEVOeFZlaH
c0WVY5NGUzWjc2cjdOcCtSdVJ0VndzdVNxb3dHK1hPSDBDSFB6WlZDc3prUVZ2RVJyTnpTb1c4aFg1Mm
UxM1YvQTFkb1EwaU4zT3hJcmRrS3dxVFZJNXoxaVJwa1liMlplbWR5QXQxY0lvUDNic1hxN2o0WDg1Wk
E9LS10N0VIYXg4Vm5xdllHVzdxa0VlUEp3PT0%3D-
-2f6a24f8d33929f e88ed19d4dea495fbb40ebed6

 请求体中的内容由请求头中的Content-Type和Content-Length决定,具体在Content-Type有展示请求体的内容

四.响应详解(Response)

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 16 Jun 2023 02:39:52 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: black_passportid=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=.sogou.com
Pragma: No-cache
Cache-Control: max-age=0
Expires: Fri, 16 Jun 2023 02:39:52 GMT
UUID: 15d42449-0c66-4731-8e40-72ff80e09202
Content-Encoding: gzip

1.常见的状态码

状态码表示访问一个页面的结果 . ( 是访问成功 , 还是失败 , 还是其他的一些情况 ...).

1.200 OK

表示访问成功

注意:在抓包的时候看到请求体被压缩的数据

网络传输中 " 带宽 " 是一个稀缺资源 , 为了传输效率更高往往会对数据进行压缩 .
我们可以点击

进行解压操作,下面就是解压后面的数据

2.403 Forbidden

表示访问被拒绝 . 有的页面通常需要用户具有一定的权限才能访问 ( 登陆后才能访问 ). 如果用户没有登陆直接访问 , 就容易见到 403.

服务器上的资源是存在的,但是没有授权给当前用户也就是说当前用户无权访问,返回403状态码

3.404 Not Found

表示没有找到资源. 这也是我们开发中常见的问题,一般是URL写错了

4.405 Method Not Allowed

客户端如果发送GET请求到服务器
服务器必然会有一个接收GET请求的方法来处理这个请求
客户端如果发送POST请求到服务器
服务器必须也会有一个接收POST请求的方法来处理这个POST请求

如果我们发送了一个post请求服务器,但是服务器没有处理post请求的方法,此时就会报405错误

5.500 Internal Server Error

服务器出现内部错误 . 一般是服务器的代码执行过程中遇到了一些特殊情况 ( 服务器异常崩溃 ) 会产生这个状态码 .

6.504 Gateway Timeout

当服务器负载比较大的时候 , 服务器处理单条请求的时候消耗的时间就会很长 , 就可能会导致出现超时的情况 .

7.301 Moved Permanently

表示永久重定向.

理解 " 重定向 "
就相当于手机号码中的 " 呼叫转移 " 功能 .
比如我本来的手机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋
友知道新号码 ,
只要我去办理一个呼叫转移业务 , 其他人拨打 186-1234-5678 , 就会自动转移到 135-1234-5678
.

常的场景是,老域名不用了,当前户访问老域名的时候强制跳转到新的域名下

 

 Location字段表示要跳转的页面

8.302 Move temporarily

表示临时重定向.

这种重定向是临时的,可能之后不需要重定向需要了.

 2.响应 "报头" (header)

1.Content-Type

响应中的Content-Type常见取值有以下几种:

  • text/html: body数据格式是HTML
  • text/css: body数据格式是CSS
  • application/javascript: body数据格式是JavaScript
  • application/json: body数据格式是JSON

五.发送POST和GET请求

1.通过form表单构建HTTP 请求

form表单的重要参数

  • action: 构造的 HTTP 请求的 URL 是什么.
  • method: 构造的 HTTP 请求的方法是 GET 还是 POST (form 只支持 GET POST).

1.GET

<body>
    <form method="get" action="calc">
        <div style="margin-top: 50px; margin-left: 50px;">
            <h1>计算器--add</h1>
            num1:<input name="num1"><br>
            num2:<input name="num2"><br>
            <input type="submit" value="相加"><br>
        </div>
    </form>
</body>

页面效果

 在文本框中输入值就可以点击相加按钮就可以按照method的方式提交到指定的action中.

get方式提交的请求我们可以看到num1和num2拼接到query string中进行传输

2.POST

<body>
    <form method="post" action="calc">
        <div style="margin-top: 50px; margin-left: 50px;">
            <h1>计算器--add</h1>
            num1:<input name="num1"><br>
            num2:<input name="num2"><br>
            <input type="submit" value="相加"><br>
        </div>
    </form>
</body>

post请求进行提交的,数据以application/x-www-form-urlencoded的格式存储在请求体(body)中

POST http://localhost:63342/Data%20Structure%20and%20Algorithm/Servlet-demo1/src/main/webapp/calc HTTP/1.1
Host: localhost:63342
Connection: keep-alive
Content-Length: 15
Cache-Control: max-age=0
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:63342
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:63342/Data%20Structure%20and%20Algorithm/Servlet-demo1/src/main/webapp/calc.html?_ijt=o10fgu7m56l1b7gr29mv0mfcmh&_ij_reload=RELOAD_ON_SAVE
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3

num1=12&num2=13

2.通过ajax构建HTTP 请求

从前端角度 , 除了浏览器地址栏能构造 GET 请求 , form 表单能构造 GET POST 之外 , 还可以通过 ajax的方式来构造 HTTP 请求 . 并且功能更强大 .
ajax 全称 A synchronous J avascript A nd X ML, 2005 年提出的一种 JavaScript 给服务器发送
HTTP 请求的方式 . (现在大多采用json来代替xml形式)
特点是可以不需要刷新页面 /页面跳转就能进行数据传输. 局部刷新,只对某些标签进行修改

ajax的最大优点:传统的form表单提交会造成页面的跳转,ajax不会造成跳转,局部更新

实现ajax方式:①XMLHttpRequest内置实现(繁琐,不做讲解)②jQuery对常用操作进行了封装(重点)

引入jquery

我们可以自行在网上下载一个的包,放在工程下面即可,推荐系在jquery.min.js,这个包更加的小,容易节省资源,使用起来的效果和非min版的一样.

 接下来就可以在head中的script标签中引入放入的jquery.

1.GET

第一种方法

jQuery.get(url,callback),第一个参数是提交的url,第二个参数是回调函数(不推荐)

            jQuery.get("calc_ajax",function (res){
                alert(res.data+" "+res.code);
            })

第二种方法(推荐)

            //发送Ajax请求到后端
            jQuery.ajax({
                url: "calc_ajax",  //提交的地址
                method: "GET",     //请求的类型
                data: {
                    "num1": num1.val(),
                    "num2": num2.val()
                },
                success: function (res) {
                    if (res.code == 200) {
                        alert("计算的结果为:"+res.data);

                    } else {
                        alert("操作失败" + res.msg);
                    }

                }
            });

发送ajax请求信息: 数据拼接在query string中

GET http://localhost:8080/Servlet_demo1_war/calc_ajax?num1=12&num2=13 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua-platform: "Windows"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/Servlet_demo1_war/calc-ajax.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3

2.POST

第一种方法

jQuery.get(url,data,callback),第一个参数是提交的url,第二个为提交的参数,第三个参数是回调函数

            jQuery.post("calc_ajax",{
                id:10,
                name:"张选宁"
                },
                function (res){
                    alert(res.data+" "+res.code);
                });

第二种方法(推荐)

            //发送Ajax请求到后端
            jQuery.ajax({
                url: "calc_ajax",  //提交的地址
                method: "POST",     //请求的类型
                data: {
                    "num1": num1.val(),
                    "num2": num2.val()
                },
                success: function (res) {
                    if (res.code == 200) {
                        alert("计算的结果为:"+res.data);

                    } else {
                        alert("操作失败" + res.msg);
                    }

                }
            });

 发送ajax请求信息: 数据在请求体(body)中

POST http://localhost:8080/Servlet_demo1_war/calc_ajax HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 15
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua-platform: "Windows"
Origin: http://localhost:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/Servlet_demo1_war/calc-ajax.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3

num1=15&num2=16

六.HTTPS

1.什么是HTTPS

HTTPS(Hyper Text Transfer Protocol Secure,安全的超文本传输协议)是一种基于 SSL/TLS 协议的 HTTP 协议,它是 HTTP 协议的安全版本。HTTPS 协议通过加密通信内容身份验证来保证数据传输的安全性和完整性,从而可以有效地防止数据在传输过程中被窃取或篡改。

HTTP的默认端口号为80,HTTPS的默认端口号为443

HTTPS = HTTP + 加密 + 认证 + 完整性保护。

2.SSL/TLS协议

SSL(Secure Socket Layer):安全套节层协议。 TLS(Transport Layer Security):传输层安全协议。 SSL(Secure Socket Layer)最早是由浏览器开发厂商网景公司开发的,此公司开发了 SSL 3.0 及 3.0 之前的版本,之后便将 SSL 交给了 IETF(Internet Engineering Task Force)Internet 工程任务组的手中,IETF 以 SSL 3.0 为基础开发了 TLS 1.0,所以可以认为 TLS 是 SSL 的“新版本”。

IETF:互联网工程任务组,致力于互联网标准的制定和推广,是互联网标准化方面的权威组织之一.

3.为什么会出现HTTPS

当我们在网络上传送数据的时候,如果我们不对数据进行加密,比如进行登录的时候,我们将账号和密码放在响应体中明文进行传输,这样一些黑客用抓包工具等手段可以劫持我们的请求信息,从而拿到我们的信息,或者拿到服务端响应给客户端的token信息,这样黑客就可以很容易的劫持到我们的个人信息,很不安全,因此我们就需要对我们在网络中传输的数据进行加密,从而不这么容易让黑客进行获取.HTTPS 就是在 HTTP 的基础上进行了加密, 进一步的来保证用户的信息安全~

4.加密和常见的加密方式

加密就是把 明文 ( 要传输的信息 ) 进行一系列变换 , 生成 密文 .
解密就是把 密文 再进行一系列变换 , 还原成 明文 .
在这个加密和解密的过程中 , 往往需要一个或者多个中间的数据 , 辅助进行这个过程 , 这样的数据称为 密钥.
具体例子:
比如我们对数字5进行传输,我们的 加密方式是将明文加上密钥,解密方式是将密文减去密钥
明文:5
加密之后:9
解密之后:5
密钥:4

1.对称加密

使用相同的密钥进行加密和解密的算法。发送方和接收方必须共享密钥才能进行通信,这使得对称加密算法在保密性和性能方面非常高效。常见的对称加密算法包括 AES(高级加密标准)和 DES(数据加密标准)

2.非对称加密

也称为公钥加密,使用一对密钥,即公钥和私钥。发送方使用接收方的公钥进行加密,而接收方使用其私钥进行解密(也可以使用私钥进行加密,公钥进行解密)。非对称加密算法可以实现加密和数字签名等功能。保密性很好,性能与对称加密对比相对比较低,常见的非对称加密算法包括 RSA 和 ECC(椭圆曲线加密).

3.哈希函数

称为散列函数,将任意长度的输入数据映射为固定长度的输出值(哈希值)。哈希函数通常用于验证数据的完整性,常见的哈希函数包括 MD5、SHA-1、SHA-256 等。哈希函数是不可逆的,即无法从哈希值还原出原始输入,但是可以对比两个数据是否相同,将一个数据加密保存,另一个数据进行加密对比.

  • 定长: 无论多长的字符串, 计算出来的 MD5 值都是固定长度 (16字节版本或者32字节版本)
  • 分散: 源字符串只要改变一点点, 最终得到的 MD5 值都会差别很大.
  • 不可逆: 通过源字符串生成 MD5 很容易, 但是通过 MD5 还原成原串理论上是不可能的.

5.什么是证书

证书 可以理解成是一个结构化的字符串 , 里面包含了以下信息 :
证书发布机构
证书有效期
公钥
证书所有者
签名
......
查看一个网站的证书,例如使用Google Chrome浏览器查看百度证书

下面是证书的基本信息

 

下面详细信息

 

6.HTTPS的工作流程

问题1:明文传送数据会让黑客获取到传输的信息.

1.引入对称加密

引入对称加密之后 , 即使数据被截获 , 由于黑客不知道密钥是啥 , 因此就无法进行解密 , 也就不知道请求的真实内容是啥了 .

 但是现在出现一个问题.服务器和客户端进行对称加密的使用需要使用的是一把密钥,这样才能同时对数据进行加密和解密.如果两者需要使用同样的密钥,一定要涉及到密钥传输的过程,也就是密钥需要由客户端传输给服务端(或者服务端传输给客户端),在密钥传输的过程中可能黑客会获取到密钥,对数据进行解密从而获取到信息,这样也是不安全的.

因此密钥的传输也需要进行加密,但此时不能使用对称加密了,如果这样的话就变成一个死循环的问题了(重复处理上面的问题).此时我们引入了非对称加密.

2.引入非对称加密

  • 客户端在本地生成对称密钥, 通过公钥给对称密钥进行加密, 发送给服务器.
  • 由于中间的网络设备没有私钥, 即使截获了数据, 也无法还原出内部的原文, 也就无法获取到对称密钥
  • 服务器通过私钥解密, 还原出客户端发送的对称密钥. 并且使用这个对称密钥加密给客户端返回的响应数据.
  • 后续客户端和服务器的通信都只用对称加密即可. 由于该密钥只有客户端和服务器两个主机知道, 其他主机/设备不知道密钥即使截获数据也没有意义.

由于对称加密的效率比非对称加密高很多, 因此只是在开始阶段协商密钥的时候使用非对称加密,
后续的传输仍然使用对称加密.

那么接下来问题又来了 :
问题一:客户端如何获取到公钥 ?
问题二:客户端如何确定这个公钥不是黑客伪造的 ?

3.引入证书

在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.

这个证书包含了刚才的公钥(解决了问题一), 也包含了网站的身份信息.

当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的).

  • 判定证书的有效期是否过期
  • 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
  • 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等.
  • 如果相等, 则说明证书是没有被篡改过的. (解决了问题二)

   理解数据摘要 / 签名
以后我们参加工作后, 经常会涉及到 "报销" 的场景. 你拿着发票想报销, 需要领导批准. 但是领导又不能和你一起去找财务. 那咋办?
很简单, 领导给你签个字就行了. 财务见到领导的签字, "见字如见人".
因为不同的人, "签名" 的差别会很大. 使用签名就可以一定程度的区分某个特定的人.
类似的, 针对一段数据(比如一个字符串), 也可以通过一些特定的算法, 对这个字符串生成一个 "签名". 并保证不同的数据, 生成的 "签名" 差别很大. 这样使用这样的签名就可以一定程度的区分不同的数据.
常见的生成签名的算法有: MD5 和 SHA 系列
以 MD5 为例, 我们不需要研究具体的计算签名的过程, 只需要了解 MD5 的特点:

  • 定长: 无论多长的字符串, 计算出来的 MD5 值都是固定长度 (16字节版本或者32字节版本)
  • 分散: 源字符串只要改变一点点, 最终得到的 MD5 值都会差别很大.
  • 不可逆: 通过源字符串生成 MD5 很容易, 但是通过 MD5 还原成原串理论上是不可能的.

正因为 MD5 有这样的特性, 我们可以认为如果两个字符串的 MD5 值相同, 则认为这两个字符串相同.

服务器阶段对证书的内容生成MD5值作为签名,然后在客户端接收到证书的时候,对此时证书的内容生成MD5,对比签名与此时生成的MD5值是否一致,如果不一致,说明证书的内容被篡改过.如果一致,说明证书内容和服务器端的一致(传输的过程中没有被篡改过),此时就可以放心的使用证书里面的公钥进行后续的操作了.

但是可能会出现这种情况,黑客拿到证书之后,对证书的内容进行了修改,并且对签名的内容重新计算了MD5取代了作为签名,客户端进行证书验证的时候就无法检测出证书是否被修改过. 这个时候就会出现问题了.此时该如何解决?

 所以被传输的签名就不能明文进行传输,也需要密文传输,而且不能使用对称加密,否则又会出现上述出现的问题,因此我们是采用非对称加密,那么此时的公钥和私钥如何获取呢?

首先私钥只能服务端从CA机构注册证书的时候进行获取,私钥是不包含在证书之中进行传输的,因此服务器端先用私钥对签名进行加密处理,然后传输给客户端(就算黑客获取到了证书,从CA机构获取到公钥,那么他对签名进行解密并修改,此时黑客无法对签名重新进行加密,客户端就能检测出证书已经被篡改了).传输到客户端的时候,客户端从CA机构获取到公钥对签名进行解密,并计算证书的MD5值与解密后的签名进行对比,检查证书是否被修改过.

这样我们就解决了所有的问题.下面是完整的流程.

4.完整流程

首先客户端内置了CA证书的公钥1,服务端向CA机构申请了证书和并获取到了私钥1,然后服务器端生成了公钥2和私钥2.客户端发送建立连接的请求,TCP三次握手建立了连接.然后服务器端将公钥2放到了证书中,并对证书内容用哈希函数(如MD5)计算哈希值作为证书的签名;并用私钥1对签名进行了加密处理.之后客户端用公钥1对签名进行解密,并计算证书的MD5值,与签名中的MD5值进行对比,如果相同就说明证书的内容没有被修改过.然后客户端生成对称密钥,取出证书中的公钥2,对对称密钥进行加密并发送给服务端,服务端使用私钥2对对称密钥进行解密,此时服务器端和客户端就都获取到了一样的对称密钥,之后双方传输的数据就采用对称密钥进行加密.

HTTPS 工作过程中涉及到的密钥有三组.
第一组 ( 非对称加密 ) : 用于校验证书是否被篡改 . 服务器持有私钥 ( 私钥在注册证书时获得 ), 客户端持有公 ( 操作系统包含了可信任的 CA 认证机构有哪些 , 同时持有对应的公钥 ). 服务器使用这个私钥对证书的 签名进行加密 . 客户端通过这个公钥解密获取到证书的签名 , 从而校验证书内容是否是篡改过 .
第二组 ( 非对称加密 ): 用于协商生成对称加密的密钥 . 服务器生成这组 私钥 - 公钥 对 , 然后通过证书把公钥传递给客户端 . 然后客户端用这个公钥给生成的对称加密的密钥加密 , 传输给服务器 , 服务器通过私钥解 密获取到对称加密密钥 .
第三组 ( 对称加密 ): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密 .
其实一切的关键都是围绕这个对称加密的密钥 . 其他的机制都是辅助这个密钥工作的 .
  • 第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器.
  • 第一组非对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥

第一组非对称加密的私钥和公钥是从CA机构间获取的,

第二组非对称加密的私钥和公钥是服务器端生成的

对称加密的密钥是客户端生成的

这个过程中涉及到了对称加密,非对称加密,哈希函数,哈希函数主要是通过证书的内容生成签名,用来验证证书是否被修改过.

通信过程的总结:

1.TCP三次握手建立连接

2.TLS握手协商密钥

3.正常通信

猜你喜欢

转载自blog.csdn.net/qq_64580912/article/details/131224709