<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      iOS URL Loading System / HTTP 重定向 認識與學習

      一個朋友問了我一個問題,需求是這樣的:他要用本地的H5資源 替換 鏈接資源,  但是判斷鏈接資源時候 因為一些操作請求本地化了之后  一些操作比如請求服務器使用的是http開頭,然而本地資源一直是以file://開頭, 這樣的

      然后 shouldStart 方法中 的request(post請求)  body  是空的,  這樣就無法到底知道是哪個鏈接了.于是就不能觸發相應的資源方法.
       
      我思考好一陣子,起初 我以為這個就是應該是 用 shouldStart 協議 根據 url 判斷 是否需要本地處理. 最終
      解決辦法是 “通過URL加載系統 (URL Loading System),攔截需要的h5資源,把本地數據直接展示
       
      原因:
      (1)利用UIWebView來處理回調地址,或者做攔截操作 一般都是得請求shouldStart協議中,甚至 需要知道請求回調結果 
       
      就是HTTP重定向的問題! 之前 真的沒有用過這個NSURLProtocol 協議去處理過問題.今天學習一下.
       
      HTTP重定向: (在網上查資料 了解到的一個比較系統的解釋)
      Redirect(客戶端重定向 我們這里研究的是)
      標準意義上的“重定向”指的是HTTP重定向,它是HTTP協議規定的一種機制。這種機制是這樣工作的:當client向server發送一個請求,要求獲取一個資源時,在server接收到這個請求后發現請求的這個資源實際存放在另一個位置,于是server在返回的response中寫入那個請求資源的正確的URL,并設置reponse的狀態碼為301(表示這是一個要求瀏覽器重定向的response),當client接受到這個response后就會根據新的URL重新發起請求。重定向有一個典型的特癥,即,當一個請求被重定向以后,最終瀏覽器上顯示的URL往往不再是開始時請求的那個URL了。這就是重定向的由來。
       
      我們在實際開發過程中 遇到過這種 服務端重定向的情況,就是 和第三方電商合作,需要展示一個訂單列表,就是我們作為客戶前端 向服務端發起請求,然后服務端發現對應資源在商城里,然后回調結果是301 /也有302,然后會繼續請求商城的訂單列表的url 然后就正常展示了.
      我們這么做的好處是: 不需要在客戶端寫死 訂單列表的請求,服務端可以動態修改訂單列表的鏈接.
       
      首先是這個注冊 NSURLProtocol協議方法可以解決的問題:
       
      籠統就是 上面提到的"Redirect(客戶端重定向)",對上層的 NSURLRequest 進行攔截,然后按需求響應操作.
      NSURLProtocol具體可以做:

      (1)如果需要,可以對html頁面中的圖片做本地化處理 

      (2)Mock假的response

      (3)對請求頭做規范化處理

      (4)在上層應用不感知情況下,實現一套代理機制

      (5)過濾請求、響應中敏感信息

      (6)對已有協議做改進、補充處理

      這些是網上查得到的,總得來說就是攔截請求時候 可以高度自定義請求方式, 攔截請求結果 高度自定義處理方法. 在實際開發中,根據具體需求處理.

      我寫了一個 實例 參考SectionDemo 的CustomUrlProtocol

      //
      //  MyURLProtocol.h
      //  NSURLProtocolExample
      //
      //  Created by HF on 2017/5/3.
      //  Copyright ? 2017年 HF. All rights reserved.
      //
      
      #import <Foundation/Foundation.h>
      
      @interface MyURLProtocol : NSURLProtocol
      
      @property (nonatomic, strong) NSMutableData *mutableData;
      @property (nonatomic, strong) NSURLResponse *response;
      
      @end
      //
      //  MyURLProtocol.m
      //  NSURLProtocolExample
      //
      //  Created by HF on 2017/5/3.
      //  Copyright ? 2017年 HF. All rights reserved.
      //
      
      #import "MyURLProtocol.h"
      #import "AppDelegate.h"
      #import "CachedURLResponseModel+CoreDataProperties.h"
      
      
      @interface MyURLProtocol () <NSURLConnectionDelegate>
      
      @property (nonatomic, strong) NSURLConnection *connection;
      
      @end
      
      @implementation MyURLProtocol
      
      /**
       *  是否攔截處理指定的請求
       *
       *  @param request 指定的請求
       *
       *  @return 返回YES表示要攔截處理,返回NO表示不攔截處理
       */
      + (BOOL)canInitWithRequest:(NSURLRequest *)request {
          static NSUInteger requestCount = 0;
          NSLog(@"Request #%lu: URL = %@", (unsigned long)requestCount++, request);
          //看看是否已經處理過了,防止無限循環
          if ([NSURLProtocol propertyForKey:@"MyURLProtocolHandledKey" inRequest:request]) {
              return NO;
          }
          return YES;
      }
      
      #pragma mark - NSURLProtocol
      
      /**
       重寫這個協議 目的是按需求條件篩選出目標請求,同時對目標request進行進一步完整包裝與定義
       
       @param request request
       @return NSURLRequest
       */
      + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
          NSMutableURLRequest *mutableReqeust = [request mutableCopy];
          mutableReqeust = [self redirectHostInRequset:mutableReqeust];
          return mutableReqeust;
      
          //return request;
      }
      
      + (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
          return [super requestIsCacheEquivalent:a toRequest:b];
      }
      
      - (void)startLoading {
          //如果想直接返回緩存的結果,構建一個CachedURLResponse對象
          
          // 1.
          CachedURLResponseModel *cachedResponse = [self cachedResponseForCurrentRequest];
          if (cachedResponse) {
              NSLog(@"serving response from cache");
              
              // 2.
              NSData *data = cachedResponse.data;
              NSString *mimeType = cachedResponse.mimeType;
              NSString *encoding = cachedResponse.encoding;
              
              // 3.
              NSURLResponse *response = [[NSURLResponse alloc] initWithURL:self.request.URL
                                                                  MIMEType:mimeType
                                                     expectedContentLength:data.length
                                                          textEncodingName:encoding];
              
              // 4.
              [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
              [self.client URLProtocol:self didLoadData:data];
              [self.client URLProtocolDidFinishLoading:self];
          } else {
              // 5.
              NSLog(@"serving response from NSURLConnection");
              
              NSMutableURLRequest *newRequest = [self.request mutableCopy];
              //標記"tag",防止無限循環
              [NSURLProtocol setProperty:@YES forKey:@"MyURLProtocolHandledKey" inRequest:newRequest];
              
              self.connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
          }
      }
      
      - (void)stopLoading {
          [self.connection cancel];
          self.connection = nil;
      }
      
      #pragma mark - NSURLConnectionDelegate
      
      - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
          [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
          
          self.response = response;
          self.mutableData = [[NSMutableData alloc] init];
      }
      
      - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
          [self.client URLProtocol:self didLoadData:data];
          
          [self.mutableData appendData:data];
      }
      
      - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
          [self.client URLProtocolDidFinishLoading:self];
          
          [self saveCachedResponse];
      }
      
      - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
          [self.client URLProtocol:self didFailWithError:error];
      }
      
      #pragma mark -- private
      
      +(NSMutableURLRequest*)redirectHostInRequset:(NSMutableURLRequest*)request
      {
          if ([request.URL host].length == 0) {
              return request;
          }
          
          NSString *originUrlString = [request.URL absoluteString];
          NSString *originHostString = [request.URL host];
          NSRange hostRange = [originUrlString rangeOfString:originHostString];
          if (hostRange.location == NSNotFound) {
              return request;
          }
          
          //定向到bing搜索主頁
          NSString *ip = @"cn.bing.com";
          
          // 替換host
          NSString *urlString = [originUrlString stringByReplacingCharactersInRange:hostRange withString:ip];
          NSURL *url = [NSURL URLWithString:urlString];
          request.URL = url;
          
          return request;
      }
      
      - (void)saveCachedResponse {
          NSLog(@"saving cached response");
          
         // if (![self.request.URL.absoluteString isEqualToString:@"cn.bing.com"]) return;
          
          // 1.
          AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
          NSManagedObjectContext *context = delegate.managedObjectContext;
          
          // 2.
          CachedURLResponseModel *cachedResponse = [NSEntityDescription insertNewObjectForEntityForName:@"CachedURLResponseModel"inManagedObjectContext:context];
          cachedResponse.data = self.mutableData;
          cachedResponse.url = self.request.URL.absoluteString;
          cachedResponse.timestamp = [NSDate date];
          cachedResponse.mimeType = self.response.MIMEType;
          cachedResponse.encoding = self.response.textEncodingName;
          
          // 3.
          NSError *error;
          BOOL const success = [context save:&error];
          if (!success) {
              NSLog(@"Could not cache the response.");
          }
      }
      
      - (CachedURLResponseModel *)cachedResponseForCurrentRequest {
          // 1.
          AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
          NSManagedObjectContext *context = delegate.managedObjectContext;
          
          // 2.
          NSFetchRequest *fetchRequest = [CachedURLResponseModel fetchRequest];
          
          // 3.
          NSPredicate *predicate = [NSPredicate predicateWithFormat:@"url == %@", self.request.URL.absoluteString];
          [fetchRequest setPredicate:predicate];
          
          // 4.
          NSError *error;
          NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
          
          // 5.
          if (result && result.count > 0) {
              return result[0];
          }
          
          return nil;
      }
      @end

      然后在需要的請求前注冊這個類

      [NSURLProtocol registerClass:[MyURLProtocol class]];

      請求結束 注銷這個類

      [NSURLProtocol unregisterClass:[MyURLProtocol class]];

       

      MyURLProtocol 里面 針對目標請求 具體按需處理

      這里 我舉得例子 是:

      首先 :請求 "https://www.raywenderlich.com" 使用 "MyURLProtocol"  注冊 攔截 該請求 然后重定向到 "cn.bing.com"上

      其次:對重定向 對象 添加緩存

      注意:

      這里只是模擬過程  沒有特此針對判斷具體鏈接,真正使用的時候大家一定要邏輯嚴謹,并且根據具體需求要做適當優化,才能靈活達到舉一反三目的。 

      參考:

      1. http://blog.csdn.net/xanxus46/article/details/51946432
      2 .http://blog.csdn.net/bluishglc/article/details/7953614
      3.http://www.molotang.com/
      4.https://www.raywenderlich.com/59982/nsurlprotocol-tutorial

      posted on 2017-05-02 10:48  ACM_Someone like you  閱讀(1778)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 天天躁日日摸久久久精品| 日韩精品三区二区三区| 东京热加勒比无码少妇| 99人体免费视频| 亚洲爆乳WWW无码专区| 亚洲av色一区二区三区| 日本一卡2卡3卡四卡精品网站| 秋霞人妻无码中文字幕| 梅州市| 国产精品一区二区不卡视频 | 国产精品揄拍一区二区久久| 国产亚洲av手机在线观看| 亚洲人成色99999在线观看| 69天堂人成无码免费视频| 18禁黄无遮挡网站免费| 国产精品熟妇视频国产偷人| 推特国产午夜福利在线观看| 日韩一区二区三区三级| 欧美人成精品网站播放| 国产成人高清亚洲综合| 中文字幕av高清片| 精品自拍偷拍一区二区三区| 亚洲人成电影网站色mp4| 三级国产三级在线| 成人欧美一区在线视频| 欧洲中文字幕国产精品| 色播久久人人爽人人爽人人片av | 国内极度色诱视频网站| 激情综合五月网| 亚洲日韩日本中文在线| 日韩精品人妻黄色一级片| 扒开双腿猛进入喷水高潮叫声| 人妻蜜臀久久av不卡| 国产精品久久久一区二区三区| 国产精品推荐手机在线| 久久夜色噜噜噜亚洲av| 亚洲一区二区三区丝袜| 男女一级国产片免费视频| 国产国产午夜福利视频| 色爱综合另类图片av| 午夜精品久久久久久久爽|