為什么要禁用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; }
文章若有不對地方,歡迎批評指正