IOS 网络请求GZIP压缩

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOS 网络请求GZIP压缩相关的知识,希望对你有一定的参考价值。

参考技术A 客户端开发过程中,难免会遇到向服务端提交大量数据的问题。为解决这个问题,优化客户端网络提交部分。于是就想到了压缩数据后再向服务端提交。

1、解决了同时大量数据上传服务器阻塞问题。

2、节省了流量。

方法:使用GZIP压缩。

第三方类:LFCGzipUtillity

   method:  

                   + (NSData *)gzipData:(NSData *)pUncompressedData;压缩方法

                   + (NSData *)uncompressZippedData:(NSData *)compressedData;解压方法

Okhttp3请求网络开启Gzip压缩

前沿

首先OkHttp3是支持Gzip解压缩的,不过我们要明白,它是支持我们在发起请求的时候自动加入header,Accept-Encoding: gzip,而我们的服务器返回的时候header中有Content-Encoding: gzip
关于更多深入的内容呢,可以参考阅读下面这篇文章,讲的非常好!
聊聊HTTP gzip压缩与常见的Android网络框架

那么,我们在向服务器提交大量数据的时候,希望对post的数据进行gzip压缩,改怎么办?
下边给出方案!

方案

官方采用的是自定义拦截器的方式!
源码在:
okhttp/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java
废话不多说,直接上代码:

 1 import java.io.IOException;
 2 
 3 import okhttp3.Interceptor;
 4 import okhttp3.MediaType;
 5 import okhttp3.Request;
 6 import okhttp3.RequestBody;
 7 import okhttp3.Response;
 8 import okio.BufferedSink;
 9 import okio.GzipSink;
10 import okio.Okio;
11 
12 public class GzipRequestInterceptor implements Interceptor {
13     @Override
14     public Response intercept(Chain chain) throws IOException {
15         Request originalRequest = chain.request();
16         if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
17             return chain.proceed(originalRequest);
18         }
19 
20         Request compressedRequest = originalRequest.newBuilder()
21                 .header("Content-Encoding", "gzip")
22                 .method(originalRequest.method(), gzip(originalRequest.body()))
23                 .build();
24         return chain.proceed(compressedRequest);
25     }
26 
27     private RequestBody gzip(final RequestBody body) {
28         return new RequestBody() {
29             @Override
30             public MediaType contentType() {
31                 return body.contentType();
32             }
33 
34             @Override
35             public long contentLength() {
36                 return -1; // 无法提前知道压缩后的数据大小
37             }
38 
39             @Override
40             public void writeTo(BufferedSink sink) throws IOException {
41                 BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
42                 body.writeTo(gzipSink);
43                 gzipSink.close();
44             }
45         };
46     }
47 }

然后构建OkhttpClient的时候,添加拦截器:

OkHttpClient okHttpClient = new OkHttpClient.Builder() 
    .addInterceptor(new GzipRequestInterceptor())//开启Gzip压缩
    ...
    .build();

后记

如果需要带有内容长度content-length的,可以查看这个issue:
Here’s the full gzip interceptor with content length, to whom it may concern:

参考:https://blog.csdn.net/tq08g2z/article/details/77311579

以上是关于IOS 网络请求GZIP压缩的主要内容,如果未能解决你的问题,请参考以下文章

5.post上传和压缩插件模拟请求

spring通过GZIP压缩提高网络传输效率(可以实现任何资源的gzip压缩包括AJAX)

vue打包时gzip压缩的两种方案

ASIHTTPRequest中数据压缩问题与gzip

Nginx Gzip 压缩

gzip格式解压缩