仅针对一个请求在 OkHttp3 中禁用重定向

Disable redirects in OkHttp3 for ONE request only

我有一个单例(Kotlin 中的 object),它包含 OkHttpClient 的实例,根据堆栈搜索,这是可行的方法。

现在我遇到这样一种情况,我的应用程序中只有一个请求,我需要跳过重定向以获取 Location header.

好像是通过

val client = OkHttpClient.Builder()
            .followRedirects(false)
            .followSslRedirects(false)
            .build()

这很好,但现在我需要存储 OkHttpClient 的两个实例和 non-redirecting 的一个甚至不总是被使用,因为它与我的应用程序的登录流程有关只有.

是否可以(例如,通过编写网络拦截器?)仅针对一个请求禁用重定向?

根据 docs,您应该使用一个主实例,然后基于该基础实例构建自定义项。

// renamed solely to make it clear what's going on below
val commonClient = OkHttpClient.Builder()
                   .followRedirects(true) // you can skip these calls, they are true by default
                   .followSslRedirects(true)
                   .build()

稍后,在您的“登录”功能中,您将创建一个基本客户端的分支。在引擎盖下,所有内容仍将使用 commonClient 但使用此“新”客户端发出的任何请求都将使用您覆盖的设置。这只是一种奇怪的迂回语法。

// fork the base instance
val noRedirectClient = commonClient.newBuilder()
                       .followRedirects(false) // override the previous/default settings used by commonClient
                       .followSslRedirects(false)
                       .build()

// make your request(s)

// don't shutdown noRedirectClient, because it would also shutdown the
// underlying commonClient instance because they share resources

你绝对可以在网络拦截器中做到这一点。可以说 @samthecodingman 解决方案更简洁,而且它绝对适用于“一个”请求。

但是如果您将其实现为拦截器,那么您不需要客户端代码知道。

在此处查看讨论

https://github.com/square/okhttp/issues/6871

类似

      client = OkHttpClient.Builder()
        .addNetworkInterceptor {
          it.proceed(it.request()).let { response ->
            if (request.url.encodedPath == "foo") {
              response.newBuilder()
                .removeHeader("Location")
                .build()
            } else {
              response
            }
          }
        }