項(xiàng)目中用到了HTTPDNS误甚,順便把做的過(guò)程和遇到的流程記錄下。
<h1>1谱净、為啥要做HttpDNS窑邦?
<h6>對(duì)于互聯(lián)網(wǎng),域名是訪問(wèn)的第一跳壕探,而這一跳很多時(shí)候會(huì)“失足”奕翔,導(dǎo)致訪問(wèn)錯(cuò)誤內(nèi)容,失敗連接等浩蓉。
HttpDNS是使用HTTP協(xié)議向DNS服務(wù)器的80端口進(jìn)行請(qǐng)求派继,代替?zhèn)鹘y(tǒng)的DNS協(xié)議向DNS服務(wù)器的53端口進(jìn)行請(qǐng)求,繞開(kāi)了運(yùn)營(yíng)商的Local DNS,從而避免了使用運(yùn)營(yíng)商Local DNS造成的劫持和跨網(wǎng)問(wèn)題捻艳。具體可以看看鵝廠的這篇文章(<a > 鵝廠DNS分析 </a>).
<h1>2驾窟、怎么做的?
<h6>我這邊選用的騰訊云的移動(dòng)解析HttpDNS认轨,接入SDK绅络,<a >SDK鏈接</a>。注意在配置的時(shí)候要在info.plist配置Demo中給出的信息嘁字,等公司申請(qǐng)下來(lái)賬號(hào)以后替換對(duì)應(yīng)的key和id恩急。
/**
域名解析ip
@param host 域名
@return ip(優(yōu)先使用ipv6),沒(méi)解析到返回host
*/
- (NSString *)dnsByDomain:(NSString *)domain {
NSTimeInterval time1 = [[NSDate date] timeIntervalSince1970];
NSArray *result = [[MSDKDns sharedInstance] WGGetHostByName:domain];
NSTimeInterval time2 = [[NSDate date] timeIntervalSince1970];
NSLog(@"HttpDNS 本次耗時(shí):%f", (time2 - time1) * 1000);
if (result && result.count > 1) {
NSString *ipv4 = result[0];
NSString *ipv6 = result[1];
if (ipv6 && ipv6.length > 1) {
NSLog(@"HttpDNS domain(%@),ip(%@)", domain, ipv6);
return [NSString stringWithFormat:@"%@", ipv6];
} else if (ipv4 && ipv4.length > 1) {
NSLog(@"HttpDNS domain(%@),ip(%@)", domain, ipv4);
return [NSString stringWithFormat:@"%@", ipv4];
}
}
return nil;
}
<h4>其中比較重要的是如何攔截網(wǎng)絡(luò)請(qǐng)求纪蜒,把其中的域名換成對(duì)應(yīng)的ip地址衷恭。
<h6>我在項(xiàng)目中,選用的是自定義NSURLProtocol的方法纯续,對(duì)于不了解的同學(xué)可以在這個(gè)地方科普下<a href="http://www.reibang.com/p/7c89b8c5482a"> NSURLProtocol 科普</a>随珠。
<h1>3、遇到的問(wèn)題
<h6>在前面兩步做的都比較順利猬错,在把域名替換成ip訪問(wèn)網(wǎng)絡(luò)的時(shí)候出現(xiàn)的問(wèn)題:“返回此服務(wù)器的證書(shū)無(wú)效窗看。您可能正在連接到一個(gè)偽裝成“14.215.177.37”的服務(wù)器,這會(huì)威脅到您的機(jī)密信息的安全(14.215.177.37 是www.baidu.com的ip)倦炒∠陨颍”
后來(lái)自信看了sdk文檔,發(fā)現(xiàn)在Https建立連接的時(shí)候是需要驗(yàn)證證書(shū)的逢唤,<a > Https場(chǎng)景處理</a>拉讯。
但是按照文檔方法寫(xiě)了后還是不能訪問(wèn),
/*
* 評(píng)估當(dāng)前serverTrust是否可信任智玻,
* 官方建議在result = kSecTrustResultUnspecified 或 kSecTrustResultProceed
* 的情況下serverTrust可以被驗(yàn)證通過(guò)遂唧,https://developer.apple.com/library/ios/technotes/tn2232/_index.html
* 關(guān)于SecTrustResultType的詳細(xì)信息請(qǐng)參考SecTrust.h
*/
SecTrustResultType result;
SecTrustEvaluate(serverTrust, &result);
return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
后來(lái)看了返回的錯(cuò)誤信息,發(fā)現(xiàn)加上result == kSecTrustResultRecoverableTrustFailure就可以正常處理了吊奢。
<h5>關(guān)于證書(shū)信任
<h6>用戶是否是自己主動(dòng)設(shè)置信任的盖彭,比如有些彈窗,用戶點(diǎn)擊了信任
1.用戶自定義的页滚,成功是 kSecTrustResultProceed 失敗是kSecTrustResultDeny
2.非用戶定義的召边, 成功是kSecTrustResultUnspecified 失敗是kSecTrustResultRecoverableTrustFailure
這個(gè)感覺(jué)是服務(wù)器的問(wèn)題,還沒(méi)有確定問(wèn)題原因裹驰。
<a > Https建立連接過(guò)程</a>