Okhttp重定向處理

重定向
客戶端向伺服器傳送一個請求,獲取對應的資源,伺服器收到請求後,發現請求的這個資源實際放在另一個位置,於是伺服器在返回的響應頭的 Location 欄位中寫入那個請求資源的正確的URL,並設定reponse的狀態碼為30x 。
相關狀態碼說明

Okhttp程式碼中的實現
在 ofollow,noindex">RetryAndFollowUpInterceptor 的 intercept方法 中構建了while (true)迴圈,根據 response 重建 request : Request followUp = followUpRequest(response)

判斷是否需要重定向的邏輯在 followUpRequest方法 中:

1.如果響應碼是307 或者308並且請求方法不是 GET 或者 HEAD 請求不進行重定向。
2.重定向的地址從響應頭中獲取 “Location”。
3.HTTPS 和 HTTP 之間的重定向,需要根據配置 followSslRedirects 來判斷。final boolean followSslRedirects; //安全套接層重定向
4.如果請求不是PROPFIND的重定向,重定向後的請求會轉為GET請求。
我們專案中的請求大都是 POST 請求或者 GET 請求,有時候為了安全考慮,全部都用 POST 請求,在遇到重定向的時候會被轉成 GET 請求,或者我們的重定向狀態碼使用的是307,並且請求方法是 GET ,Okhttp就不支援了。這就不符合我們的要求了。有時候還可能實現跨域重定向,如:HTTP -> HTTPS。
既然Okhttp預設的實現不能滿足我們的要求,就需要我們自己去實現,其實實現很簡單,我們只需要自定義一個攔截器,判斷重定向的響應碼,然後從響應頭中獲取重定向後的地址,重新請求一遍即可。
重定向處理
//處理重定向的攔截器 public class RedirectInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { okhttp3.Request request = chain.request(); Response response = chain.proceed(request); int code = response.code(); if (code == 307) { //獲取重定向的地址 String location = response.headers().get("Location"); LogUtils.e("重定向地址:", "location = " + location); //重新構建請求 Request newRequest = request.newBuilder().url(location).build(); response = chain.proceed(newRequest); } return response; } } //使用 OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false);//禁制OkHttp的重定向操作,我們自己處理重定向 .addInterceptor(new RedirectInterceptor()) .build();