日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

ip访问 webstorem_常见问题-iOS WebView IP直连 如何处理 Cookie

發(fā)布時(shí)間:2024/1/23 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ip访问 webstorem_常见问题-iOS WebView IP直连 如何处理 Cookie 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

WKWebView 無(wú)法使用 NSURLProtocol 攔截請(qǐng)求

針對(duì)該問(wèn)題方案如下:

換用 UIWebView

使用私有 API 進(jìn)行注冊(cè)攔截

換用 UIWebView 方案不做贅述,說(shuō)明下使用私有 API 進(jìn)行注冊(cè)攔截的方法 :

// 注冊(cè)自己的 protocol

[NSURLProtocol registerClass:[CustomProtocol class]];

// 創(chuàng)建 WKWebview

WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc] init];

WKWebView * wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:config];

[wkWebView loadRequest:webViewReq];

[self.view addSubview:wkWebView];

//注冊(cè) scheme

Class cls = NSClassFromString(@"WKBrowsingContextController");

SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");

if ([cls respondsToSelector:sel]) {

// 通過(guò) http 和 https 的請(qǐng)求,同理可通過(guò)其他的 Scheme 但是要滿(mǎn)足 ULR Loading System

[cls performSelector:sel withObject:@"http"];

[cls performSelector:sel withObject:@"https"];

}

使用私有 API 的另一風(fēng)險(xiǎn)是兼容性問(wèn)題,比如上面的 `browsingContextController` 就只能在 iOS 8.4 以后才能用,反注冊(cè) scheme 的方法 `unregisterSchemeForCustomProtocol :` 也是在 iOS 8.4 以后才被添加進(jìn)來(lái)的,要支持 iOS 8.0 ~ 8.3 機(jī)型的話(huà),只能通過(guò)動(dòng)態(tài)生成字符串的方式拿到 `WKBrowsingContextController`,而且還不能反注冊(cè),不過(guò)這些問(wèn)題都不大。至于向后兼容,這個(gè)也不用太擔(dān)心,因?yàn)?iOS 發(fā)布新版本之前都會(huì)有開(kāi)發(fā)者預(yù)覽版的,那個(gè)時(shí)候再測(cè)一下也不遲。對(duì)于本文的例子來(lái)說(shuō),如果將來(lái)哪個(gè) iOS 版本移除了這個(gè) API,那很可能是因?yàn)楣俜教峁┝送暾慕鉀Q方案,到那時(shí)候自然也不需要本文介紹的方法了 。

注意: 避免執(zhí)行太晚,如果在 `- (void)viewDidLoad` 中注冊(cè),可能會(huì)因?yàn)樽?cè)太晚,引發(fā)問(wèn)題。建議在 `+load` 方法中執(zhí)行 。

然后同樣會(huì)遇到 [《 HTTPS SNI 業(yè)務(wù)場(chǎng)景 “ IP直連 ” 方案說(shuō)明 》](https://help.aliyun.com/document_detail/60147.html) 里提到的各種 NSURLProtocol 相關(guān)的問(wèn)題,可以參照里面的方法解決 。

WebView 中的 Cookie 處理業(yè)務(wù)場(chǎng)景 IP直連 方案說(shuō)明

下文將討論類(lèi)似這樣的問(wèn)題 :

WKWebView 對(duì)于 Cookie 的管理一直是它的短板,那么 iOS11 是否有改進(jìn),如果有,如何利用這樣的改進(jìn) ?

采用 IP 直連方案后,服務(wù)端返回的 Cookie 里的 Domain 字段也會(huì)使用 IP 。如果 IP 是動(dòng)態(tài)的,就有可能導(dǎo)致一些問(wèn)題:由于許多 H5 業(yè)務(wù)都依賴(lài)于 Cookie 作登錄態(tài)校驗(yàn) ,而 WKWebView 上請(qǐng)求不會(huì)自動(dòng)攜帶 Cookie 。

WKWebView 使用 NSURLProtocol 攔截請(qǐng)求無(wú)法獲取 Cookie 信息

iOS 11 推出了新的 API WKHTTPCookieStore 可以用來(lái)攔截 WKWebView 的 Cookie 信息

用法示例如下 :

WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;

// get cookies

[cookieStroe getAllCookies:^(NSArray * _Nonnull cookies) {

NSLog(@"All cookies %@",cookies);

}];

// set cookie

NSMutableDictionary *dict = [NSMutableDictionary dictionary];

dict[NSHTTPCookieName] = @"userid";

dict[NSHTTPCookieValue] = @"123";

dict[NSHTTPCookieDomain] = @"xxxx.com";

dict[NSHTTPCookiePath] = @"/";

NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:dict];

[cookieStroe setCookie:cookie completionHandler:^{

NSLog(@"set cookie");

}];

// delete cookie

[cookieStroe deleteCookie:cookie completionHandler:^{

NSLog(@"delete cookie");

}];

利用 iOS 11 API WKHTTPCookieStore 解決 WKWebView 首次請(qǐng)求不攜帶 Cookie 的問(wèn)題

問(wèn)題說(shuō)明:由于許多 H5 業(yè)務(wù)都依賴(lài)于 Cookie 作登錄態(tài)校驗(yàn),而 WKWebView 上請(qǐng)求不會(huì)自動(dòng)攜帶 Cookie 。比如,如果你在 Native 層面做了登陸操作,獲取了 Cookie 信息,也使用 NSHTTPCookieStorage 存到了本地,但是使用 WKWebView 打開(kāi)對(duì)應(yīng)網(wǎng)頁(yè)時(shí),網(wǎng)頁(yè)依然處于未登陸狀態(tài)。如果是登陸也在 WebView 里做的,就不會(huì)有這個(gè)問(wèn)題。

iOS 11 的 API 可以解決該問(wèn)題,只要是存在 WKHTTPCookieStore 里的 cookie,WKWebView 每次請(qǐng)求都會(huì)攜帶,存在 NSHTTPCookieStorage 的 cookie,并不會(huì)每次都攜帶。于是會(huì)發(fā)生首次 WKWebView 請(qǐng)求不攜帶 Cookie 的問(wèn)題。

解決方法:

在執(zhí)行 -[WKWebView loadReques:] 前將 NSHTTPCookieStorage 中的內(nèi)容復(fù)制到 WKHTTPCookieStore 中,以此來(lái)達(dá)到 WKWebView Cookie 注入的目的。示例代碼如下:

[self copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:^{

NSURL *url = [NSURL URLWithString:@"https://www.v2ex.com"];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

[_webView loadRequest:request];

}];

- (void)copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:(nullable void (^)())theCompletionHandler; {

NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;

if (cookies.count == 0) {

!theCompletionHandler ?: theCompletionHandler();

return;

}

for (NSHTTPCookie *cookie in cookies) {

[cookieStroe setCookie:cookie completionHandler:^{

if ([[cookies lastObject] isEqual:cookie]) {

!theCompletionHandler ?: theCompletionHandler();

return;

}

}];

}

}

這個(gè)是 iOS 11 的 API ,針對(duì) iOS 11 之前的系統(tǒng) ,需要另外處理。

作為一個(gè)開(kāi)發(fā)者,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,這有個(gè)iOS交流群:642363427,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經(jīng)驗(yàn),討論技術(shù),iOS開(kāi)發(fā)者一起交流學(xué)習(xí)成長(zhǎng)!

利用 iOS 11 之前的 API 解決 WKWebView 首次請(qǐng)求不攜帶 Cookie 的問(wèn)題

通過(guò)讓所有 WKWebView 共享同一個(gè) WKProcessPool 實(shí)例,可以實(shí)現(xiàn)多個(gè) WKWebView 之間共享 Cookie(session Cookie and persistent Cookie)數(shù)據(jù)。不過(guò) WKWebView WKProcessPool 實(shí)例在 app 殺進(jìn)程重啟后會(huì)被重置,導(dǎo)致 WKProcessPool 中的 Cookie、session Cookie 數(shù)據(jù)丟失,目前也無(wú)法實(shí)現(xiàn) WKProcessPool 實(shí)例本地化保存。可以采取 cookie 放入 Header 的方法來(lái)做。

WKWebView * webView = [WKWebView new];

NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://xxx.com/login"]];

[request addValue:@"skey=skeyValue" forHTTPHeaderField:@"Cookie"];

[webView loadRequest:request];

其中對(duì)于 skey=skeyValue 這個(gè) cookie 值的獲取,也可以統(tǒng)一通過(guò) domain 獲取,獲取的方法,可以參照下面的工具類(lèi):

HTTPDNSCookieManager.h

#ifndef HTTPDNSCookieManager_h

#define HTTPDNSCookieManager_h

// URL匹配Cookie規(guī)則

typedef BOOL (^HTTPDNSCookieFilter)(NSHTTPCookie *, NSURL *);

@interface HTTPDNSCookieManager : NSObject

+ (instancetype)sharedInstance;

/**

指定URL匹配Cookie策略

@param filter 匹配器

*/

- (void)setCookieFilter:(HTTPDNSCookieFilter)filter;

/**

處理HTTP Reponse攜帶的Cookie并存儲(chǔ)

@param headerFields HTTP Header Fields

@param URL 根據(jù)匹配策略獲取查找URL關(guān)聯(lián)的Cookie

@return 返回添加到存儲(chǔ)的Cookie

*/

- (NSArray *)handleHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)URL;

/**

匹配本地Cookie存儲(chǔ),獲取對(duì)應(yīng)URL的request cookie字符串

@param URL 根據(jù)匹配策略指定查找URL關(guān)聯(lián)的Cookie

@return 返回對(duì)應(yīng)URL的request Cookie字符串

*/

- (NSString *)getRequestCookieHeaderForURL:(NSURL *)URL;

/**

刪除存儲(chǔ)cookie

@param URL 根據(jù)匹配策略查找URL關(guān)聯(lián)的cookie

@return 返回成功刪除cookie數(shù)

*/

- (NSInteger)deleteCookieForURL:(NSURL *)URL;

@end

#endif /* HTTPDNSCookieManager_h */

HTTPDNSCookieManager.m

#import

#import "HTTPDNSCookieManager.h"

@implementation HTTPDNSCookieManager

{

HTTPDNSCookieFilter cookieFilter;

}

- (instancetype)init {

if (self = [super init]) {

/**

此處設(shè)置的Cookie和URL匹配策略比較簡(jiǎn)單,檢查URL.host是否包含Cookie的domain字段

通過(guò)調(diào)用setCookieFilter接口設(shè)定Cookie匹配策略,

比如可以設(shè)定Cookie的domain字段和URL.host的后綴匹配 | URL是否符合Cookie的path設(shè)定

細(xì)節(jié)匹配規(guī)則可參考RFC 2965 3.3節(jié)

*/

cookieFilter = ^BOOL(NSHTTPCookie *cookie, NSURL *URL) {

if ([URL.host containsString:cookie.domain]) {

return YES;

}

return NO;

};

}

return self;

}

+ (instancetype)sharedInstance {

static id singletonInstance = nil;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

if (!singletonInstance) {

singletonInstance = [[super allocWithZone:NULL] init];

}

});

return singletonInstance;

}

+ (id)allocWithZone:(struct _NSZone *)zone {

return [self sharedInstance];

}

- (id)copyWithZone:(struct _NSZone *)zone {

return self;

}

- (void)setCookieFilter:(HTTPDNSCookieFilter)filter {

if (filter != nil) {

cookieFilter = filter;

}

}

- (NSArray *)handleHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)URL {

NSArray *cookieArray = [NSHTTPCookie cookiesWithResponseHeaderFields:headerFields forURL:URL];

if (cookieArray != nil) {

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in cookieArray) {

if (cookieFilter(cookie, URL)) {

NSLog(@"Add a cookie: %@", cookie);

[cookieStorage setCookie:cookie];

}

}

}

return cookieArray;

}

- (NSString *)getRequestCookieHeaderForURL:(NSURL *)URL {

NSArray *cookieArray = [self searchAppropriateCookies:URL];

if (cookieArray != nil && cookieArray.count > 0) {

NSDictionary *cookieDic = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];

if ([cookieDic objectForKey:@"Cookie"]) {

return cookieDic[@"Cookie"];

}

}

return nil;

}

- (NSArray *)searchAppropriateCookies:(NSURL *)URL {

NSMutableArray *cookieArray = [NSMutableArray array];

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in [cookieStorage cookies]) {

if (cookieFilter(cookie, URL)) {

NSLog(@"Search an appropriate cookie: %@", cookie);

[cookieArray addObject:cookie];

}

}

return cookieArray;

}

- (NSInteger)deleteCookieForURL:(NSURL *)URL {

int delCount = 0;

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in [cookieStorage cookies]) {

if (cookieFilter(cookie, URL)) {

NSLog(@"Delete a cookie: %@", cookie);

[cookieStorage deleteCookie:cookie];

delCount++;

}

}

return delCount;

}

@end

使用方法示例:

發(fā)送請(qǐng)求

WKWebView * webView = [WKWebView new];

NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://xxx.com/login"]];

NSString *value = [[HTTPDNSCookieManager sharedInstance] getRequestCookieHeaderForURL:url];

[request setValue:value forHTTPHeaderField:@"Cookie"];

[webView loadRequest:request];

接收處理請(qǐng)求:

NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

if (!error) {

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;

// 解析 HTTP Response Header,存儲(chǔ)cookie

[[HTTPDNSCookieManager sharedInstance] handleHeaderFields:[httpResponse allHeaderFields] forURL:url];

}

}];

[task resume];

通過(guò) document.cookie 設(shè)置 Cookie 解決后續(xù)頁(yè)面(同域)Ajax、iframe 請(qǐng)求的 Cookie 問(wèn)題;

WKUserContentController* userContentController = [WKUserContentController new];

WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: @"document.cookie = 'skey=skeyValue';" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

[userContentController addUserScript:cookieScript];

Cookie包含動(dòng)態(tài) IP 導(dǎo)致登陸失效問(wèn)題

關(guān)于 COOKIE 失效的問(wèn)題,假如客戶(hù)端登錄 session 存在 COOKIE,此時(shí)這個(gè)域名配置了多個(gè) IP,使用域名訪(fǎng)問(wèn)會(huì)讀對(duì)應(yīng)域名的 COOKIE,使用IP訪(fǎng)問(wèn)則去讀對(duì)應(yīng) IP 的 COOKIE,假如前后兩次使用同一個(gè)域名配置的不同 IP 訪(fǎng)問(wèn),會(huì)導(dǎo)致 COOKIE 的登錄 session 失效,

如果 APP 里面的 webview 頁(yè)面需要用到系統(tǒng) COOKIE 存的登錄 session,之前 APP 所有本地網(wǎng)絡(luò)請(qǐng)求使用域名訪(fǎng)問(wèn),是可以共用 COOKIE 的登錄 session 的,但現(xiàn)在本地網(wǎng)絡(luò)請(qǐng)求使用 httpdns后改用 IP 訪(fǎng)問(wèn),導(dǎo)致還使用域名訪(fǎng)問(wèn)的 webview 讀不到系統(tǒng) COOKIE 存的登錄 session 了(系統(tǒng) COOKIE 對(duì)應(yīng) IP 了)。IP 直連后,服務(wù)端返回 Cookie 包含動(dòng)態(tài) IP 導(dǎo)致登陸失效。

使用 IP 訪(fǎng)問(wèn)后,服務(wù)端返回的 cookie 也是 IP。導(dǎo)致可能使用對(duì)應(yīng)的域名訪(fǎng)問(wèn),無(wú)法使用本地 cookie,或者使用隸屬于同一個(gè)域名的不同 IP 去訪(fǎng)問(wèn),cookie 也對(duì)不上,導(dǎo)致登陸失效 。

我這邊的思路是這樣的,

應(yīng)該得干預(yù) cookie 的存儲(chǔ),基于域名。

根源上,api 域名返回單 IP

第二種思路將失去 DNS 調(diào)度特性,故不考慮。第一種思路更為可行。

基于 iOS11 API WKHTTPCookieStore 來(lái)解決 WKWebView 的 Cookie 管理問(wèn)題

當(dāng)每次服務(wù)端返回cookie后,在存儲(chǔ)前都進(jìn)行下改造,使用域名替換下IP。之后雖然每次網(wǎng)絡(luò)請(qǐng)求都是使用IP訪(fǎng)問(wèn),但是host我們都手動(dòng)改為了域名,這樣本地存儲(chǔ)的 cookie 也就能對(duì)得上了。

代碼演示:

在網(wǎng)絡(luò)請(qǐng)求成功后,或者加載網(wǎng)頁(yè)成功后,主動(dòng)將本地的 domain 字段為 IP 的 Cookie 替換 IP 為 host 域名地址。

- (void)updateWKHTTPCookieStoreDomainFromIP:(NSString *)IP toHost:(NSString *)host {

WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;

[cookieStroe getAllCookies:^(NSArray * _Nonnull cookies) {

[[cookies copy] enumerateObjectsUsingBlock:^(NSHTTPCookie * _Nonnull cookie, NSUInteger idx, BOOL * _Nonnull stop) {

if ([cookie.domain isEqualToString:IP]) {

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:cookie.properties];

dict[NSHTTPCookieDomain] = host;

NSHTTPCookie *newCookie = [NSHTTPCookie cookieWithProperties:[dict copy]];

[cookieStroe setCookie:newCookie completionHandler:^{

[self logCookies];

[cookieStroe deleteCookie:cookie

completionHandler:^{

[self logCookies];

}];

}];

}

}];

}];

}

iOS 11 中也提供了對(duì)應(yīng)的 API 供我們來(lái)處理替換 Cookie 的時(shí)機(jī),那就是下面的 API:

@protocol WKHTTPCookieStoreObserver

@optional

- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore;

@end

//WKHTTPCookieStore

/*! @abstract Adds a WKHTTPCookieStoreObserver object with the cookie store.

@param observer The observer object to add.

@discussion The observer is not retained by the receiver. It is your responsibility

to unregister the observer before it becomes invalid.

*/

- (void)addObserver:(id)observer;

/*! @abstract Removes a WKHTTPCookieStoreObserver object from the cookie store.

@param observer The observer to remove.

*/

- (void)removeObserver:(id)observer;

用法如下:

@interface WebViewController ()

- (void)viewDidLoad {

[super viewDidLoad];

[NSURLProtocol registerClass:[WebViewURLProtocol class]];

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore;

[cookieStroe addObserver:self];

[self.view addSubview:self.webView];

//... ...

}

#pragma mark -

#pragma mark - WKHTTPCookieStoreObserver Delegate Method

- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore {

[self updateWKHTTPCookieStoreDomainFromIP:CYLIP toHost:CYLHOST];

}

-updateWKHTTPCookieStoreDomainFromIP 方法的實(shí)現(xiàn),在上文已經(jīng)給出。

這個(gè)方案需要客戶(hù)端維護(hù)一個(gè)IP —> HOST的映射關(guān)系,需要能從 IP 反向查找到 HOST,這個(gè)維護(hù)成本還時(shí)挺高的。下面介紹下,更通用的方法,也是iOS11 之前的處理方法:

iOS 11 之前的處理方法:NSURLProtocal 攔截后,手動(dòng)管理 Cookie 的存儲(chǔ):

步驟:做 IP 替換時(shí)將原始 URL 保存到 Header 中

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {

NSMutableURLRequest *mutableReq = [request mutableCopy];

NSString *originalUrl = mutableReq.URL.absoluteString;

NSURL *url = [NSURL URLWithString:originalUrl];

// 異步接口獲取IP地址

NSString *ip = [[HttpDnsService sharedInstance] getIpByHostAsync:url.host];

if (ip) {

NSRange hostFirstRange = [originalUrl rangeOfString:url.host];

if (NSNotFound != hostFirstRange.location) {

NSString *newUrl = [originalUrl stringByReplacingCharactersInRange:hostFirstRange withString:ip];

mutableReq.URL = [NSURL URLWithString:newUrl];

[mutableReq setValue:url.host forHTTPHeaderField:@"host"];

// 添加originalUrl保存原始URL

[mutableReq addValue:originalUrl forHTTPHeaderField:@"originalUrl"];

}

}

NSURLRequest *postRequestIncludeBody = [mutableReq cyl_getPostRequestIncludeBody];

return postRequestIncludeBody;

}

然后獲取到數(shù)據(jù)后,手動(dòng)管理 Cookie :

- (void)handleCookiesFromResponse:(NSURLResponse *)response {

NSString *originalURLString = [self.request valueForHTTPHeaderField:@"originalUrl"];

if ([response isKindOfClass:[NSHTTPURLResponse class]]) {

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;

NSDictionary *allHeaderFields = httpResponse.allHeaderFields;

if (originalURLString && originalURLString.length > 0) {

NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:allHeaderFields forURL: [[NSURL alloc] initWithString:originalURLString]];

if (cookies && cookies.count > 0) {

NSURL *originalURL = [NSURL URLWithString:originalURLString];

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:originalURL mainDocumentURL:nil];

}

}

}

}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest *))completionHandler {

NSString *location = response.allHeaderFields[@"Location"];

NSURL *url = [[NSURL alloc] initWithString:location];

NSMutableURLRequest *mRequest = [newRequest mutableCopy];

mRequest.URL = url;

if (location && location.length > 0) {

if ([[newRequest.HTTPMethod lowercaseString] isEqualToString:@"post"]) {

// POST重定向?yàn)镚ET

mRequest.HTTPMethod = @"GET";

mRequest.HTTPBody = nil;

}

[mRequest setValue:nil forHTTPHeaderField:@"host"];

// 在這里為 request 添加 cookie 信息。

[self handleCookiesFromResponse:response];

[XXXURLProtocol removePropertyForKey:XXXURLProtocolHandledKey inRequest:mRequest];

completionHandler(mRequest);

} else{

completionHandler(mRequest);

}

}

發(fā)送請(qǐng)求前,向請(qǐng)求中添加Cookie信息:

+ (void)handleCookieWithRequest:(NSMutableURLRequest *)request {

NSString* originalURLString = [request valueForHTTPHeaderField:@"originalUrl"];

if (!originalURLString || originalURLString.length == 0) {

return;

}

NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

if (cookies && cookies.count >0) {

NSDictionary *cookieHeaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];

NSString *cookieString = [cookieHeaders objectForKey:@"Cookie"];

[request addValue:cookieString forHTTPHeaderField:@"Cookie"];

}

}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {

NSMutableURLRequest *mutableReq = [request mutableCopy];

//...

[self handleCookieWithRequest:mutableReq];

return [mutableReq copy];

}

推薦👇:

如果你想一起進(jìn)階,不妨添加一下交流群642363427

總結(jié)

以上是生活随笔為你收集整理的ip访问 webstorem_常见问题-iOS WebView IP直连 如何处理 Cookie的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。