如何在Glide v4 / OkHttp3中检测重定向?



使用 Glide v4 和 OkHttp3,如何检测重定向并在发生重定向时加载另一个 url?

我的用例:我使用带有 OkHttp3 的 Glide v4 库在我的应用程序中下载图片。有时,当图片不可用时,服务器会执行重定向以提供另一张图片,而不是我最初想要的图片。我可以在浏览器中看到它,因为当我请求网址 A 时,我最终登陆带有第二张图片的网址 B。发生这种情况时,我想改为加载从 url A 派生的 url C(因此不是静态 url(。

目前,我可以使用 OkHttp3 拦截器检测重定向:

public Response intercept(@NonNull Chain chain) throws IOException {
String requestUrl = chain.request().url().toString();
Response response = chain.proceed(chain.request());
String responseUrl = response.request().url().toString();
boolean redirect = !requestUrl.equals(responseUrl);
if (redirect) {
Timber.d("Detected redirection");
}
return response;
}

但我不知道如何干净地加载网址 C。我不明白如何在拦截器中加载另一个 url,如果我抛出 IOException 来处理稍后在 Glide RequestListener 中的错误,它只会导致 GlideException,所以我无法确定它为什么被抛出。

默认情况下,OkHttp 应该会自动重定向并加载最终内容。 请参阅 OkHttpClient.Builder.followRedirects。

https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.Builder.html#followRedirects-boolean-

我自己的测试表明这是有效的,例如

$ oksocial 'https://httpbin.org/redirect-to?url=https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg'

为了检测它,我假设您的拦截器是通过addInterceptor而不是addNetworkInterceptor注册的。 这是对的吗?

同样值得确保重定向是通过 30X 响应而不是通过 HTML 刷新。

我最终得到的解决方案非常丑陋:我在问题中显示的请求拦截器在检测到重定向时会引发 IOException。然后,我将使用 GlideListener 来检测错误,并加载 url C。丑陋的部分是,在GlideListener中,我无法确定错误的原因,它可能是重定向,但也可能是网络错误或其他任何东西。

这个解决方案的更干净版本可能可以通过自定义的 OkHttpUrlLoader 来实现,但对于我的简单用例来说,它的代码太多了。

这是我在Glide v4/OkHttp3中的解决方案

String redirect = response.header("location");
if(redirect != null && !request.url().toString().equals(redirect)) {
// if redirected your code here
}

最新更新