client:
向server發送一個請求,要求獲取一個資源
server:
接收到這個請求後,發現請求的這個資源實際存放在另外一個位置
因而server在返回的response header的Location字段中寫入那個請求資源的正確的URL,並設置reponse的狀態碼爲30x
client:
接收到這個response後,發現狀態碼爲重定向的狀態嗎,就會去解析到新的URL,根據新的URL從新發起請求javascript
重定向最經常使用爲301,也有303,
臨時重定向用302,307java
請求轉發
服務器在處理request的過程當中將request前後委託多個servlet或jsp接替進行處理的過程,request和reponse始終在期間傳遞git
重定向:
用戶請求-----》服務器入口-------》組件------>服務器出口-------》用戶----(重定向)---》新的請求
請求轉發
用戶請求-----》服務器入口-------》組件1---(轉發)----》組件2------->服務器出口-------》用戶github
response.sendRedirect()
在RetryAndFollowUpInterceptor的intercept方法中構建了while (true)循環,循環內部:瀏覽器
###1. 根據response重建request:Request followUp = followUpRequest(response)服務器
int responseCode = userResponse.code();複製代碼
而後switch (responseCode)進行判斷:網絡
將前一步獲得的followUp 賦值給request,從新進入循環,jsp
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
...
while (true) {
if (canceled) {
streamAllocation.release();
throw new IOException("Canceled");
}
Response response = null;
boolean releaseConnection = true;
try {
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);//執行網絡請求
releaseConnection = false;
...
Request followUp = followUpRequest(response);//拿到重定向的request
if (followUp == null) {
if (!forWebSocket) {
streamAllocation.release();
}
return response;//若是不是重定向,就返回response
}
...
if (++followUpCount > MAX_FOLLOW_UPS) {//有最大次數限制20次
streamAllocation.release();
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
request = followUp;//把重定向的請求賦值給request,以便再次進入循環執行
priorResponse = response;
}
}複製代碼
重定向功能默認是開啓的,能夠選擇關閉,而後去實現本身的重定向功能:ide
new OkHttpClient().newBuilder()
.followRedirects(false) //禁制OkHttp的重定向操做,咱們本身處理重定向
.followSslRedirects(false)//https的重定向也本身處理複製代碼