最近遇到這么一件事兒优训,網(wǎng)頁在個別中國移動4G網(wǎng)絡(luò)下叛赚,訪問白屏
環(huán)境:iOS 14 部分移動4G網(wǎng)絡(luò)
問題: WKWebView, 回調(diào)commitNavigation 之后虫几,一直在等待肺稀,didFinish一直執(zhí)行不到鳍侣。
經(jīng)過測試丁稀,定位到 script位置,script使用了一個并不存在的網(wǎng)絡(luò)地址倚聚,放到wkWebview中就導(dǎo)致了頁面一直在加載线衫,但是加載不出來,直到網(wǎng)頁超時(一般30-60秒)
html代碼如下(偽代碼)
<header>
<script src="https://some.url.cannot.find.js"></script>
</header>
測試發(fā)現(xiàn)惑折,就算在iphone的safari中授账,直接訪問一個不存在地址枯跑,safari地址欄下的進(jìn)度條會一直在讀條,持續(xù)進(jìn)5分鐘才會提示無法鏈接白热。
為了解決這個問題
其實這個是中國移動的問題全肮,他通過dns沒找到,那就報錯唄棘捣,他就不辜腺,任性
提出了幾種方案
- 攔截h5頁面,提前處理掉有問題的h5
- 攔截相關(guān)請求乍恐,直接返回失敗评疗。
- H5改
- 方案1: 失敗茵烈!
在webView request的之前百匆,通過AFNetWorking直接請求H5的text,然后替換文字呜投,替換后直接使用
[aWebView loadHTMLString:@"替換后的htmlString" baseURL: baseURL];
但是問題出現(xiàn)了:因為變成了本地的string加匈,因此html里面一些相對地址的資源文件都丟失了,如 圖片仑荐、css雕拼、js等等。
如果都轉(zhuǎn)成本地粘招,那么代價就太大了
因此這邊想了一個辦法啥寇,攔截相關(guān)的請求
*方案2:
wkWebView提供了WKURLSchemeHandler供我們攔截請求,但不允許攔截http https ftp等洒扎,但是可以通過Category 重寫系統(tǒng)方法來實現(xiàn)辑甜,具體做法百度知道。
也發(fā)生了個bug袍冷,百度提的不多磷醋,就是攔截的請求回丟失body,導(dǎo)致其他的相關(guān)請求都失敗了! 失敗的代碼如下:
if ([urlSchemeTask.request.URL.absoluteString isEqualToString:@"https://some.host.com/www/cordova.js"] || [urlSchemeTask.request.URL.absoluteString isEqualToString:@"https://some.host.com/www/js/index.js"]) {
NSError * error = [NSError errorWithDomain:NSURLErrorDomain code:404 userInfo:@{NSLocalizedDescriptionKey: @"request unsupportted js content"}];
[urlSchemeTask didFailWithError:error];
}
解決問題的方法也很簡單胡诗,就是使用AF邓线,直接請求網(wǎng)頁數(shù)據(jù),通過WKURLSchemeHandler提供的代理方法傳遞給webView乃戈,做法與攔截自定義sheme后褂痰,加載本地資源的過程如出一轍亩进,代碼如下:
if ([urlSchemeTask.request.URL.absoluteString isEqualToString:@"https://some.host.com/www/cordova.js"] || [urlSchemeTask.request.URL.absoluteString isEqualToString:@"https://some.host.com/www/js/index.js"]) {
NSError * error = [NSError errorWithDomain:NSURLErrorDomain code:404 userInfo:@{NSLocalizedDescriptionKey: @"request unsupportted js content"}];
[urlSchemeTask didFailWithError:error];
} else {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlSchemeTask.request.URL];
AFURLSessionManager * manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:NSURLSessionConfiguration.defaultSessionConfiguration];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSURLSessionDataTask * task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSData * data = (NSData *)responseObject;
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
}];
[task resume];
}
- 方案3: 最好了症虑,我就不說了。