资讯专栏INFORMATION COLUMN

OkHttp如何移除User-Agent,Accept-Encoding等框架自动添加的请求头参数

Eirunye / 2825人阅读

摘要:移除头部参数然后再将自定义的拦截器设置为网络拦截器信任所有证书设置应用拦截器无效,因为是在应用拦截器之后添加的这样就能达到移除自动添加的请求头参数的目的了。

使用OkHttp网络框架在进行网络请求时会发现,传到后台的请求头中会比我们自己添加的参数多出几个额外参数。查看源码会发现

 private Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!retryAndFollowUpInterceptor.isForWebSocket()) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(
        retryAndFollowUpInterceptor.isForWebSocket()));

    Interceptor.Chain chain = new RealInterceptorChain(
        interceptors, null, null, null, 0, originalRequest);
    return chain.proceed(originalRequest);
  }

OkHttp会默认添加一个桥接拦截器BridgeInterceptor,查看BridgeInterceptor的源码

MediaType contentType = body.contentType();
      if (contentType != null) {
        requestBuilder.header("Content-Type", contentType.toString());
      }

      long contentLength = body.contentLength();
      if (contentLength != -1) {
        requestBuilder.header("Content-Length", Long.toString(contentLength));
        requestBuilder.removeHeader("Transfer-Encoding");
      } else {
        requestBuilder.header("Transfer-Encoding", "chunked");
        requestBuilder.removeHeader("Content-Length");
      }
    }

    if (userRequest.header("Host") == null) {
      requestBuilder.header("Host", hostHeader(userRequest.url(), false));
    }

    if (userRequest.header("Connection") == null) {
      requestBuilder.header("Connection", "Keep-Alive");
    }

    // If we add an "Accept-Encoding: gzip" header field we"re responsible for also decompressing
    // the transfer stream.
    boolean transparentGzip = false;
    if (userRequest.header("Accept-Encoding") == null) {
      transparentGzip = true;
      requestBuilder.header("Accept-Encoding", "gzip");
    }

    List cookies = cookieJar.loadForRequest(userRequest.url());
    if (!cookies.isEmpty()) {
      requestBuilder.header("Cookie", cookieHeader(cookies));
    }

    if (userRequest.header("User-Agent") == null) {
      requestBuilder.header("User-Agent", Version.userAgent());
    }

在BridgeInterceptor中会默认添加User-Agent,Accept-Encoding等请求头参数。有时候我们并不需要这些默认添加的参数,那么我们如何才能做到移除它们呢?

通过上面第一段的部分源码

interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
  interceptors.addAll(client.networkInterceptors());
}

可以看到OkHttp内部在添加完BridgeInterceptor后,才开始添加networkInterceptors,所以我们需要借助网络拦截器来重新拦截请求头,并操作头部参数。

首先我们要自定义一个拦截器,在拦截器中移除我们不需要的参数。

public class NetInterceptorimplements Interceptor {

    private HttpClient builder;

    public NetInterceptor() {
        super();
    }

    public NetInterceptor(HttpClient builder) {
        this.builder = builder;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        //移除头部参数
        request = request.newBuilder()
                    .removeHeader("User-Agent")
                    .removeHeader("Accept-Encoding")
                    .build();
        Response response = chain.proceed(request);
        if (response.body() != null && response.body().contentType() != null) {
            MediaType mediaType = response.body().contentType();
            String content = response.body().string();
            ResponseBody responseBody = ResponseBody.create(mediaType, content);
            return response.newBuilder().body(responseBody).build();
        } else {
            return response;
        }
    }

}

然后再将自定义的拦截器设置为网络拦截器

  mOkBuilder = new Builder()
                .connectTimeout(mbuilder.getConnectTimeout(), TimeUnit.SECONDS)
                .readTimeout(mbuilder.getReadTimeout(), TimeUnit.SECONDS)
                .writeTimeout(mbuilder.getWriteTimeout(), TimeUnit.SECONDS)
                .sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())// 信任所有证书
                .hostnameVerifier(new TrustAllHostnameVerifier())
                .cookieJar(new CookieJar() {
                    private final HashMap> cookieStore = new HashMap<>();

                    @Override
                    public void saveFromResponse(HttpUrl httpUrl, List list) {
                        cookieStore.put(httpUrl.host(), list);
                    }

                    @Override
                    public List loadForRequest(HttpUrl httpUrl) {
                        List cookies = cookieStore.get(httpUrl.host());
                        return cookies != null ? cookies : new ArrayList();
                    }
                });

  NetInterceptor netInterceptor = new NetInterceptor(mbuilder);
  //mOkBuilder.addNetworkInterceptor(netInterceptor);//设置应用拦截器无效,因为BridgeInterceptor是在应用拦截器之后添加的
  mOkBuilder.addNetworkInterceptor(netInterceptor);

这样就能达到移除BridgeInterceptor自动添加的请求头参数的目的了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14318.html

相关文章

  • OkHttp如何移除User-AgentAccept-Encoding框架自动添加请求参数

    摘要:移除头部参数然后再将自定义的拦截器设置为网络拦截器信任所有证书设置应用拦截器无效,因为是在应用拦截器之后添加的这样就能达到移除自动添加的请求头参数的目的了。 使用OkHttp网络框架在进行网络请求时会发现,传到后台的请求头中会比我们自己添加的参数多出几个额外参数。查看源码会发现 private Response getResponseWithInterceptorChain() th...

    newsning 评论0 收藏0
  • RxEasyHttp一款基于RxJava2+Retrofit2实现简单易用网络请求框架

    摘要:注和是当下非常火爆的开源框架,均来自神一般的公司。特点比使用更简单更易用。默认初始化如果使用默认始化后,一切采用默认设置。为单个请求设置超时,比如涉及到文件的需要设置读写等待时间多一点。 github源码地址:https://github.com/zhou-you/RxEasyHttp RxEasyHttp 本库是一款基于RxJava2+Retrofit2实现简单易用的网络请求框架,结...

    MadPecker 评论0 收藏0
  • HTTPie 官方文档中文翻译版

    摘要:目标是让与的交互尽可能的更友好。在版本以上已经成为了默认的版本。不同类型的键值对分割符号分别是。这将会协商服务端和你安装的支持的最高协议版本。 博客原文» HTTPie 是一个命令行 HTTP 客户端。目标是让 CLI 与 Web services 的交互尽可能的更友好。它提供了一个简单的 http 命令,可以让我们用简单自然的表述发送任意 HTTP 请求,并且可以输出带代码高亮的结果...

    Baaaan 评论0 收藏0
  • Android八门神器(一): OkHttp框架源码解析

    摘要:控制最大请求并发数和单个主机的最大并发数,并持有一个线程池负责执行异步请求,对同步的请求只是用作统计。在每个分离器使用一个内部调用请求内部主要并不涉及执行的具体。HTTP是我们交换数据和媒体流的现代应用网络,有效利用HTTP可以使我们节省带宽和更快地加载数据,Square公司开源的OkHttp网络请求是有效率的HTTP客户端。之前的知识面仅限于框架API的调用,接触到实际的工作之后深知自己知...

    番茄西红柿 评论0 收藏0
  • 聊聊 Android 网络请求框架 Retrofit 2 + okhttp 3

    摘要:解决后端没有找到优雅的解决方式被迫修改接口实现之所以继续保留是为了兼容其它调用方处理逻辑时先判断是否有值没有的话再从取研究写过一点不太相信想自己试试。打听后得知客户端的网络框架是配合。开始研究安装环境就不说了。 工作中跟客户端沟通时产生了点问题, 记录一下. 起因 后端有一个接口是这样的 @RequestMapping(android) public BaseResult androi...

    刘明 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<