07.OkHttp网络请求设计
目录介绍
- 01.整体概述介绍
- 1.1 项目设计思想
- 1.2 一些基础概念
- 1.3 设计目标
- 1.4 最简单的使用
- 1.5 简单版网络库
- 1.6 Get请求数据
- 1.7 Post提交数据
- 1.8 问题思考一下
- 02.开发设计思路
- 2.1 整体设计思路
- 2.2 创建请求Client
- 2.3 封装Request
- 2.4 设计Call请求
- 2.5 同步和异步设计
- 2.6 Dispatcher设计
- 2.7 拦截器的设计
- 2.8 缓存拦截的设计
- 2.9 连接请求设计
- 2.10 返回response
- 03.OkHttp原理思考
- 3.2 创建Client操作
- 3.3 request实践
- 3.4 Call请求流程
- 3.5 同步和异步原理
- 3.6 拦截器实践
- 3.7 缓存拦截实现
- 3.8 连接请求实现
- 3.9 response处理
- 04.一些技术点思考
- 4.1 如何解析接口url
- 4.2 如何做域名解析
- 4.3 Dispatcher调度
- 4.4 如何设计高效流
- 4.5 如何设计缓存
- 4.6 如何设计连接请求
- 4.8 如何设计线程池
- 05.一些应用实践
- 5.1 如何统计网络耗时
- 5.2 如何上传图片&文件
- 5.3
- 5.4
- 06.必要的基础知识
- 6.1 URI和URL基础概念
- 6.2 为何要用Https
- 6.3
01.整体概述介绍
1.1 项目设计思想
- 设计Okhttp必须要高性能
- 并发和异步性能设计:OkHttp通过使用连接池、请求复用、异步执行等技术,提供了高性能的HTTP通信能力。它能够自动管理连接、复用连接以减少网络延迟,并支持异步执行请求以提高并发性能。
- 支持HTTP/2和WebSocket
- OkHttp支持HTTP/2协议和WebSocket通信,这些协议提供了更高效的数据传输和双向通信能力。它能够自动适应和升级到HTTP/2协议,以提供更好的性能和效率。
- 异步和回调机制设计
- OkHttp支持异步执行HTTP请求,并提供了回调机制来处理请求的结果。能够方便地进行网络请求和处理响应。
- 如何考虑安全性
- OkHttp提供了对HTTPS的支持,包括证书验证、TLS版本选择等。它能够自动处理证书验证和安全连接的建立,以确保通信的安全性和可靠性。
1.2 一些基础概念
1.4 最简单的使用
- 最简单的同步和异步调用
Response response = okHttpClient.newCall(request).execute(); okHttpClient.newCall(request).enqueue(callback);
- 有哪些比较重要的类
- OKHttpClient类,这个是创建请求客户端对象
- Request类和Response类,这个是发送请求和接收响应
- Call类和RealCall类,这个是创建call请求操作,Call对象(一个准备好了的可以执行和取消的请求)。
- Dispatcher类,这个是分发器。
1.5 简单版网络库
1.6 Get请求数据
- Get同步请求数据
String url = "www.baidu.com/index"; OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); try { Response response = okHttpClient.newCall(request).execute(); String body = response.body().string(); Log.d("body---yc---",body); } catch (IOException e) { e.printStackTrace(); }
- Get异步请求数据
okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { } @Override public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException { String body = response.body().string(); Log.d("body---yc---",body); } });
1.7 Post提交数据
- Post提交数据四种方式如下
- 第一种:Map 通过 GSON 转为 JSON
- 第二种:使用MultipartBody提交表单 form-data
- 第三种:JSONObject
- 第四种:使用FormBody提交表单数据,x-www-form-urlencoded
- 第一种方式核心代码【Map 通过 GSON 转为 JSON】
RequestBody requestBody = FormBody.create(mediaType, gson.toJson(map)); Request.Builder builder = new Request.Builder().url(url); Request request = builder.post(requestBody).build(); Call call = client.newCall(request); Response resp = call.execute();
- 第二种方式核心代码【表单 form-data】
MultipartBody.Builder bodyBuilder = new MultipartBody .Builder() .setType(MultipartBody.FORM); bodyBuilder.addFormDataPart("word", "西红柿炒鸡蛋"); Request.Builder builder = new Request.Builder().url(url); builder.post(bodyBuilder.build()); Call call = client.newCall(builder.build()); Response resp = call.execute();
- 第三种方式核心代码【JSONObject方式】
JSONObject json = new JSONObject(); json.put("word", "西红柿炒鸡蛋"); json.put("page", "1"); RequestBody bodyBuilder = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json.toString()); Request.Builder builder = new Request.Builder().url(url); builder.post(bodyBuilder).build(); Call call = client.newCall(builder.build()); Response resp = call.execute();
1.8 问题思考一下
- OkHttp简单介绍
- 1.支持HTTP2/SPDY
- 2.socket自动选择最好路线,并支持自动重连
- 3.拥有自动维护的socket连接池,减少握手次数
- 4.拥有队列线程池,轻松写并发
- 5.拥有Interceptors轻松处理请求与响应(比如透明GZIP压缩)基于Headers的缓存策略
- OkHttp问题思考分析
- OkHttp设计:OkHttp整体设计思路是什么样的?request和respond分别如何设计?如何设计call请求操作?
- OkHttp同步异步:如何设计同步和异步请求?同步操作做了什么?异步操作如何处理逻辑?
- OkHttp拦截器:拦截器是如何设计的?为什么需要拦截器?拦截器如何处理拦截,和向下分发逻辑?如何做重试机制的设计?
- OkHttp缓存:如何设计缓存?什么情况下会用到网络缓存?缓存拦截器的核心思想是什么?
- OkHttp分发器:同步和异步请求的Dispatcher是如何调度的?设计的巧妙之处是什么?
- OkHttp线程池:使用了什么线程池?是如何管理线程任务?跟普通线程池使用有何区别?
02.开发设计思路
2.1 整体设计思路
- 首先放一张完整流程图(看不懂没关系,慢慢往后看):
image
- 网络请求到响应大概流程图如下所示
image
- 整体设计思路大概如下所示
- 第一步:创建OkHttpClient对象,由于创建这个对象十分复杂,因此采用builder设计模式构造
- 第二步:包装Request请求体对象,主要是存放url,header,get请求,post请求等等属性
- 第三步:通过newCall(request)去创建一个call请求
- 第四步:开始执行同步execute或者enqueue请求,这里会使用到线程池
- 第五步:添加各种拦截器,缓存拦截器,
- 第六步:处理缓存拦截,数据复用的技术逻辑
- 第七步:创建连接请求的操作,给服务端发送请求
- 第八步:获取返回response数据,这里主要是处理code和body数据
2.2 创建请求Client
- 为何要创建Client
- 创建OkHttpClient对象,主要是用于Api网络请求的对象。类似于初始化网络请求,可以设置超时时间,日志打印拦截器,代理,ssl校验,域名校验等等。
- 创建OkHttpClient如下所示
okHttpClient = new OkHttpClient.Builder() .addInterceptor(new LoggerInterceptor()) .connectTimeout(15, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .build();
2.3 封装Request
- Request抽象成请求数据
- Request包括Headers和RequestBody,而RequestBody是abstract的,他的子类是有FormBody(表单提交的)和MultipartBody(文件上传),分别对应了两种不同的MIME类型。
FormBody :"application/x-www-form-urlencoded" MultipartBody:"multipart/"+xxx.
- 关于Headers说明,头部信息不是随便写的
- OKHttp的封装类Request和Response为了应用程序编程方便,会把一些常用的Header信息专门提取出来,作为局部变量。
- 比如contentType,contentLength,code,message,cacheControl,tag...它们其实都是以name-value对的形势,存储在网络请求的头部信息中。
- Request类用于表示一个HTTP请求。它的设计主要包括以下几个方面
- URL和HTTP方法:Request类包含了请求的URL和HTTP方法(GET、POST、PUT等)。
- 请求头:Request类提供了方法来设置和获取请求头信息。可以通过addHeader()方法添加单个请求头,或者通过headers()方法获取请求头的构建器。
- 请求体:对于POST、PUT等需要发送请求体的请求,Request类提供了设置和获取请求体的方法。可以通过RequestBody对象来表示请求体的内容。
- 缓存控制:Request类支持设置缓存控制相关的信息,例如设置Cache-Control头部字段,以控制缓存的行为。
- 用户认证:Request类支持设置基本的HTTP身份验证,可以通过设置Authorization头部字段来进行用户认证。
2.4 设计Call请求
- 如何设计Call请求
- 基于接口开发,设计了Call接口,里面主要做同步请求execute,异步请求enqueue,取消请求cancel等等。
- Call类详解
- 有道词典翻译该类注释:调用是准备执行的请求。call可以取消。由于此对象表示单个请求/响应对(流),因此不能执行两次。
- 主要是HTTP请求任务封装
- 可以说我们能用到的操纵基本上都定义在这个接口里面了,可以通过Call对象来操作请求,同步请求execute,异步请求enqueue。
- 而Call接口内部提供了Factory工厂方法模式(将对象的创建延迟到工厂类的子类去进行,从而实现动态配置)。
- 来看一下Call操作的代码流程
final Call call = okHttpClient.newCall(request);
- Call核心请求操作放到了
RealCall
类中,它是Call
接口的实现类,提供一个可靠、高效的HTTP请求执行机制。- 1.提供核心异步/同步执行请求:
RealCall
使用线程池来执行请求,使得请求可以在后台线程中进行,而不会阻塞主线程。 - 2.拦截器链:
RealCall
使用拦截器链来处理请求和响应。通过拦截器链,可以实现请求的修改、日志记录、缓存控制、身份验证等功能。
- 1.提供核心异步/同步执行请求:
2.5 同步和异步设计
- 先思考一个问题
- 为什么要设计同步和异步?如果让你来设计,你该如何设计同步和异步操作,如何将异步请求按照顺序执行?
- 同步和异步设计Api设计
okHttpClient.newCall(request).execute(); okHttpClient.newCall(request).enqueue(callback);
- 同步和异步处理任务流程图?
image
- 网络请求肯定涉及多线程,如何处理大量任务
- 采用Dispatcher作为调度,与线程池配合实现了高并发,低阻塞的的运行。针对请求任务,采用Deque作为集合,按照入队的顺序先进先出。
2.6 Dispatcher设计
- 先思考一个问题
- 假设有100个网络接口请求,那么你是如何控制并发数量,如何设计取消某个请求操作,如何设置请求优先级?
- OkHttp设计Dispatcher的主要目的是为了管理和调度多个并发的HTTP请求。
- 并发请求管理:Dispatcher负责管理并发的HTTP请求。它使用线程池来控制并发请求的数量,可以限制同时执行的请求数量。
- 请求队列:Dispatcher维护一个请求队列,用于存储等待执行的请求。
- 异步执行:Dispatcher支持异步执行HTTP请求。它使用线程池来执行请求,使得请求可以在后台线程中进行,而不会阻塞主线程。
- 请求取消和中断:Dispatcher允许取消和中断正在执行的请求。
- 优先级调度:Dispatcher支持为请求设置优先级。通过设置请求的优先级,可以控制请求的执行顺序,优先处理高优先级的请求。
2.7 拦截器的设计
OKHttp
有两种调用方式,一种是阻塞的同步请求,一种是异步的非阻塞的请求。- 但是无论同步还是异步都会调用下
RealCall
的getResponseWithInterceptorChain
方法来完成请求,同时将返回数据或者状态通过Callback
来完成。
- 但是无论同步还是异步都会调用下
- 设计拦截器的核心原理:Interceptor 负责拦截和分发。
- 先来看看含义:观察,修改以及可能短路的请求输出和响应请求的回来。通常情况下拦截器用来添加,移除或者转换请求或者回应的头部信息。
- 拦截器,就像水管一样,把一节一节的水管(拦截器)连起来,形成一个回路。实际上client到server也是如此,通过一个又一个的interceptor串起来,然后把数据发送到服务器,又能接受返回的数据,每一个拦截器(水管)都有自己的作用,分别处理不同东西,比如消毒,净化,去杂质,就像一层层过滤网一样。
- 接口是如何设计的
public interface Interceptor { //负责拦截 Response intercept(Chain chain) throws IOException; interface Chain { //负责分发、前行 Response proceed(Request request) throws IOException; } }
- 那么如何分发操作。这块可以看:RealInterceptorChain
- 大概思路:RealInterceptorChain持有一个List的Interceptor,通过对这个List的Interceptor进行迭代和递归推进调用
- 每一个RealInterceptorChain对应一个interceptor,然后每一个interceptor再产生下一个RealInterceptorChain,直到List迭代完成。
2.8 缓存拦截的设计
2.9 连接请求设计
- ConnectInterceptor的设计
- 连接拦截器,这才是真行的开始向服务器发起器连接。
2.10 返回response
- Response抽象成响应数据
- Response包括Headers和RequestBody,而ResponseBody是abstract的,所以他的子类也是有两个:RealResponseBody和CacheResponseBody,分别代表真实响应和缓存响应。
03.OkHttp原理思考
3.2 创建Client操作
- OKHttpClient
- 1、里面包含了很多对象,其实OKHttp的很多功能模块都包装进这个类,让这个类单独提供对外的API,这种外观模式的设计十分的优雅。外观模式。
- 2、而内部模块比较多,就使用了Builder模式(建造器模式)。Builder模式(建造器模式)
- 3、它的方法只有一个:newCall.返回一个Call对象(一个准备好了的可以执行和取消的请求)。
3.3 request实践
- 主要是封装一个Request请求体。
Request request = new Request.Builder() .url(url) .addHeader("cookie","yangchong") .get() .build();
3.4 Call请求流程
- 相当于调用newCall去创建一个call请求,这里分为同步和异步操作
okHttpClient.newCall(request).execute(); okHttpClient.newCall(request).enqueue(callback);
- RealCall类构造创建对象,它是Call接口的具体实现类。
- 在源码中,OKHttpClient实现了Call.Factory接口,返回了一个RealCall对象。那我们就来看下RealCall这个类。
- 1、OkHttpClient的newCall方法里面new了RealCall的对象,但是RealCall的构造函数需要传入一个OKHttpClient对象和Request对象(PS:第三个参数false表示不是webSokcet)。因此RealCall包装了Request对象。所以RealCall可以很方便地使用这两个对象。
- 2、RealCall里面的两个关键方法是:execute 和 enqueue。分别用于同步和异步得执行网络请求。
- 3、RealCall还有一个重要方法是:getResponseWithInterceptorChain,添加拦截器,通过拦截器可以将一个流式工作分解为可配置的分段流程,既增加了灵活性也实现了解耦,关键还可以自有配置,非常完美。
3.5 同步和异步原理
- execute同步调用流程
RealCall#execute(),这个主要是执行同步操作的核心方法。首先是判断call是否执行过,可以看出每个Call对象只能使用一次原则。 Dispatcher#executed(),将任务添加到Deque队列中 Dispatcher#executed(),里面发现是runningSyncCalls执行了add方法,可以发现runningSyncCalls是ArrayDeque对象。 Dispatcher#runningSyncCalls,它是双向队列,runningSyncCalls是一个存放同步请求的双向队列。 RealCall#getResponseWithInterceptorChain(),这个是添加各种拦截器,然后创建RealInterceptorChain对象执行请求操作 getResponseWithInterceptorChain()#interceptors.add,不断地add各种拦截器。有重定向,缓存,连接,自定义拦截器等等。 RealInterceptorChain#proceed,在这个里面获取拦截器,看到在proceed方面里面又new了一个RealInterceptorChain类的next对象 这个next对象和chain最大的区别就是index属性值不同chain是0.而next是1,然后取interceptors下标为1的对象的interceptor。 由从上文可知,如果没有开发者自定义的Interceptor时,首先调用的RetryAndFollowUpInterceptor,如果有开发者自己定义的interceptor则调用开发者interceptor。 interceptor#intercept(),最后通过拦截器请求操作,获取response响应数据
- enqueue异步调用流程
RealCall#enqueue(callback),由于executed默认为false,所以先进行判断是否为true,为true则直接跑异常,没有则设置为true,可以看出executed这个是一个标志,标志这个请求是否已经正在请求中 Dispatcher#enqueue(),是Dispatcher对象所以实际调用的是Dispatcher的enqueue() Dispatcher#readyAsyncCalls,readyAsyncCalls是一个存放异步请求的双向队列。 Dispatcher#promoteAndExecute(),将符合条件的调用从{readyAsyncCalls}提升到{runningAsyncCalls},并在executor服务上运行它们。 Dispatcher#promoteAndExecute()#asyncCall.executeOn,遍历去执行异步任务 RealCall#AsyncCall#executeOn(),创建一个executorService去执行runnable任务。在子线程中做任务 NamedRunnable#run(),然后去执行execute()方法,该方法是抽象的。具体看子类对该方法的实现。 RealCall#AsyncCall#execute,又调用了getResponseWithInterceptorChain(),这块跟同步调用逻辑一样。然后通过responseCallback处理结果。
3.6 拦截器实践
- interceptor接口详解
- Interceptor是一个接口,主要是对请求和相应的过滤处理,其中有一个抽象方法即Response intercept(Chain chain) throws IOException负责具体的过滤。
- 在他的子类里面又调用了Chain,从而实现拦截器调用链(chain),所以真正实现拦截作用的是其内部接口Chain。
- Interceptor.Chain的实现类都是RealInterceptorChain,也就说说处理调用过程的实现是RealInterceptorChain。
- 所以RealInterceptorChain持有一个List的Interceptor,通过对这个List的Interceptor进行迭代和递归推进。让我们看看源码实现。
- RealInterceptorChain#proceed()很核心的操作步骤理解如下
- 第一步,先判断是否超过list的size,如果超过则遍历结束,如果没有超过则继续执行
- 第二步calls+1
- 第三步new了一个RealInterceptorChain,其中然后下标index+1
- 第四步 从list取出下一个interceptor对象
- 第五步 执行interceptor的intercept方法
- RealInterceptorChain#proceed()核心思想设计
- 每一个RealInterceptorChain对应一个interceptor,然后每一个interceptor再产生下一个RealInterceptorChain,直到List迭代完成。
- 拦截器中的设计模式
- 既一个网络请求,按一定的顺序,经由多个拦截器进行处理,该拦截器可以决定自己处理并且返回我的结果,也可以选择向下继续传递,让后面的拦截器处理返回它的结果。这个设计模式叫做责任链模式。
3.7 缓存拦截实现
3.8 连接请求实现
3.9 response处理
- Response类说明
- Response抽象成响应数据
- Response包括Headers和RequestBody,而ResponseBody是abstract的,所以他的子类也是有两个:RealResponseBody和CacheResponseBody,分别代表真实响应和缓存响应。
04.一些技术点思考
4.1 如何解析接口url
- 如果让你设计网络请求框架,你是如何保证请求的接口是可靠合规的?
- 可以设计一个处理url验证和规范化的类,提供解析URL是一种可靠和推荐的方式。
- 可以使用
HttpUrl
类来解析和操作URL。- 要解析
URL
,可以使用HttpUrl
的静态方法parse(),将URL
字符串作为参数传入,返回一个HttpUrl
对象。例如: - 通过
HttpUrl
对象,可以获取URL
的各个部分,例如协议、主机、路径、查询参数等。
String urlString = "https://www.example.com/path?param1=value1¶m2=value2"; HttpUrl httpUrl = HttpUrl.parse(urlString);
- 要解析
4.2 如何做域名解析
4.3 Dispatcher调度
- 线程池executeService的设计
- 创建一个自定义ThreadPoolExecutor线程池对象。需要注意两点:
- 第一点:在OKHttp中,创建了一个阀值是Integer.MAX_VALUE的线程池;第二点:SynchronousQueue每个插入操作必须等待另一个线程的移除操作。
- 发起网络请求
- 整个框架主要通过Call来封装每一次的请求。同时Call持有OkHttpClient和一份Request。而每一次的同步或者异步请求都会有Dispatcher的参与。
- 同步:Dispatcher在执行同步的Call,接加入到runningSyncCall队列中,实际上并没有执行该Call,而是交给外部执行。
- 异步:将Call加入readyAsyncCall排队等待,将符合条件的调用从{readyAsyncCalls}提升到{runningAsyncCalls},并在executor服务上运行它们。
- 异步操作中符合条件是指,如果当前正在执行的call的数量大于maxRequest(64),或者该call的Host上的call超过maxRequestsPerHos(5),则加入readyAsyncCall排队等待,否则加入runningAsyncCalls并执行。
- 结束网络请求
- 具体看 RealCall#AsyncCall#executeOn()和execute():从ready到running,在每个call结束的时候都会调用finished【这个是在try-finally中执行的】。
- OKHttp同步调度流程分析
- 第一步:是调用了RealCall的execute()方法里面调用executed(this);
- 第二步:在Dispatcher里面的executed执行入队操作
- 第三步:执行getResponseWithInterceptorChain();进入拦截器链流程,然后进行请求,获取Response,并返回Response result 。
- 第四步:执行client.dispatcher().finished(this)操作
- OKHttp异步调度流程分析
- 第一步:是调用了RealCall的enqueue()方法
- 第二步:在Dispatcher里面的enqueue执行入队操作。这个地方有条件
- runningAsyncCalls.size() < maxRequests 表示当前正在运行的AsyncCall是否小于maxRequests = 64
- runningCallsForHost(call) < maxRequestsPerHos 表示同一个地址访问的AsyncCall是否小于maxRequestsPerHost = 5;即 当前正在并发的请求不能超过64且同一个地址的访问不能超过5个
- 第A步:第一种情况A
- 第三步:可以直接入队。把任务放到runningAsyncCalls中
- 第四步:线程池executorService执行execute()方法
- 第五步:执行AsyncCall的execute()方法
- 第六步:执行getResponseWithInterceptorChain();进入拦截器链流程,然后进行请求,获取Response。
- 第七步:执行client.dispatcher().finished(this)操作 进行出队操作
- 第B步:第二种情况B
- 第三步:不能直接入队,需要等待。把任务放到readyAsyncCalls中,能进入等待则说明当前要么有64条正在进行的并发,要么同一个地址有5个请求,所以要等待。
- 第四步:先判断是否满足 初步入队条件。如果此时 并发的数量还是大于maxRequests=64则return并继续等待;如果此时,没有等待的任务,则直接return并继续等待。
- 第五步:在Dispatcher#promoteAndExecute()中,此时满足条件,则从等待队列面移除这个call【i.remove()】,然后添加到正在运行的队列中【runningAsyncCalls.add(asyncCall)】。
- 第六步:线程池executorService执行execute()方法
- 第七步:执行AsyncCall的execute()方法
- 第八步:执行getResponseWithInterceptorChain();进入拦截器链流程,然后进行请求,获取Response。
- 第九步:如果是正常的获取到Response,则执行responseCallback.onResponse()
- 第十步:执行client.dispatcher().finished(this)操作 进行出队操作
05.一些应用实践
5.1 如何统计网络耗时
- OkHttp如何进行各个请求环节的耗时统计呢?
- OkHttp 版本提供了EventListener接口,可以让调用者接收一系列网络请求过程中的事件,例如DNS解析、TSL/SSL连接、Response接收等。
- 通过继承此接口,调用者可以监视整个应用中网络请求次数、流量大小、耗时(比如dns解析时间,请求时间,响应时间等等)情况。
- 如何消耗记录时间
- 在OkHttp库中有一个EventListener类。该类是网络事件的侦听器。扩展这个类以监视应用程序的HTTP调用的数量、大小和持续时间。
- 所有启动/连接/获取事件最终将接收到匹配的结束/释放事件,要么成功(非空参数),要么失败(非空可抛出)。
- 比如,可以在开始链接记录时间;dns开始,结束等方法解析记录时间,可以计算dns的解析时间。
- 比如,可以在开始请求记录时间,记录connectStart,connectEnd等方法时间,则可以计算出connect连接时间。
- 关于网络耗时请求的内容
- Okhttp统计耗时技术博客:OkHttp请求耗时统计
- Okhttp统计耗时技术库:MonitorNetLib
6.2 为何要用Https
- 在没有HTTPS之前使用HTTP的协议的,可见HTTPS肯定是弥补的HTTP的安全缺陷,那么咱们来看下HTTP协议的那些安全缺点:
- 1、通信使用明文(不加密),内容可能被窃听(抓包工具可以获取请求和响应内容),如下图:
image - 2、不验证通讯方的身分,任何人都坑你发送请求,不管对方是谁都返回相应,如下图:
image - 3、无法证明报文的完整性,可能会遭到篡改,即没有办法确认发出的请求/相应前后一致。
image - 所以为了解决上述问题,需要在HTTP上加入加密处理和认证机制,我们把添加了加密和认证机制的http称之为http。
- HTTP+加密+认证+完成性保护=HTTPS。简单的说下HTTPS说下他的优势
- 1、内容加密,建立一个信息的安全通道,来保证数据传输过程的安全性。
- 2、身份认证,确认网站的真是性。
- 3、数据完整性,防止内容被第三方冒充或者篡改。
- 补充一下:HTTPS并非应用层的一种新协议
- 只是HTTP通讯接口部分用SSL(secure socket layer)和TLS(transport layer security)协议代替。
- 通常HTTP直接和TCP通信时,当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通讯,因此所以HTTPS其实就是身披SSL保护外衣的HTTP。