為什么要禁用URL Scheme和Universal Link(通用鏈接)
通常我們APP中都會嵌套一些web頁面,有時我們的web頁面會被DNS劫持從而跳轉到其他APP中;或者是某些APP的Universal Link(通用鏈接)設置的比較容易觸發,當web跨域跳轉就有可能跳轉到這些APP。比如蘇寧易購的Universal Link(通用鏈接)為*.m.suning.com,只要web進行跨域跳轉*.m.suning.com就會拉起蘇寧易購APP。在這種情況下的話我們就需要在我們的APP中對web做一些處理從而來禁止拉起這些APP。
在iOS 9.0之后如果需要使用URL Scheme喚起APP的話需要在info.plist中增加白名單,只有在白名單中的URL Scheme才可以使用,因此可以禁止跳轉到意料之外的APP。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>openapp.jdmobile</string>
</array>
WKWebView
在iOS8.0后APP推出的WKWebView是現有大部分APP中常用的控件之一。
-
WKWebView中URL Scheme禁用和啟用即使在info.plist中設置了白名單但是
WKWebView對URL Scheme默認是不支持的,如果要支持URL Scheme需要做一些處理- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL *url = navigationAction.request.URL; // 調用電話 if ([url.scheme isEqualToString:@"tel"]) { if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; decisionHandler(WKNavigationActionPolicyCancel); return; } } decisionHandler(WKNavigationActionPolicyAllow); } -
WKWebView中Universal Link(通用鏈接)禁用對於
Universal Link(通用鏈接)的話因為該方式是通過系統層級來直接拉起APP的,在WKWebView也是可以無縫跳轉的。如果需要禁用Universal Link(通用鏈接)的話只需要在WKNavigationDelegate的- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler中WKNavigationActionPolicyAllow替換成WKNavigationActionPolicyAllow+2:- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { decisionHandler(WKNavigationActionPolicyAllow+2); }
UIWebView
雖然iOS8.0后提供了WKWebView,但是如果需要手動管理cookie的話(WKWebView在iOS11.0之后才可以手動管理cookie)或其他原因還是又很大一部分使用UIWebView的APP。
-
UIWebView中URL Scheme禁用
在iOS9.0之后對於UIWebView只有URL Scheme配置在info.plist中才可以正常使用,因此對URL Scheme不需要做特殊處理。
在iOS 9.0之前在UIWebView中禁用URL Scheme需要我們在- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;代理方法中做一些處理。
首先我們可以依然設置白名單列表,例如:self.whiteSchemes = @[@"http",@"https"];當跳轉的Scheme不在我們的白名單中就禁止跳轉:- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *url = request.URL; if (![self.whiteSchemes containsObject:url.scheme]) { return NO; } return YES; } -
UIWebView中Universal Link(通用鏈接)禁用
其實在APP中嵌套的web頁面大部分都是自己家的頁面,因此域名應該是固定的。因此在UIWebView中禁用Universal Link(通用鏈接)我只想到用最笨的方法和禁用URL Scheme方式一樣。
設置白名單列表,但是和白名單列表中存放的是host(域名)而不是Scheme,例如:self.whiteHosts = @[@"http",@"https"];。當跳轉的不是白名單中的話就直接禁止跳轉。- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *url = request.URL; if (![self.whiteHosts containsObject:url.host]) { return NO; } return YES; }
文章若有不對地方,歡迎批評指正
