Set useragent in WKWebview
如何在WKWebView中设置自定义useragent字符串? 我试图嵌入我的应用程序的版本,以便服务器端可以看到可用的功能。 我发现以下方法:
1 2 3 4 5 6 7 8 | let userAgent ="MyApp/1.33.7" request.setValue(userAgent, forHTTPHeaderField:"User-Agent") NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in let content = NSString(data: data, encoding: NSUTF8StringEncoding) self.web!.loadHTMLString(content!, baseURL: url) } self.web!.loadRequest(request); |
但这意味着仅针对该单个请求设置useragent。 其他第一个请求(例如转发)将意味着将用户代理再次重置为默认设置。 如何更永久地配置wkwebview以使用我的自定义useragent字符串?
您会很高兴听到
例:
1 | wkWebView.customUserAgent ="your agent" |
更新:
从iOS 9.0开始,可以直接设置用户代理(如其他答案所述)。但是要注意,设置它会完全覆盖默认的用户代理,这一点很重要。如果出于某些原因您只需要追加自定义用户代理,请使用以下方法之一。
1 2 3 4 5 | webView.evaluateJavaScript("navigator.userAgent") { [weak webView] (result, error) in if let webView = webView, let userAgent = result as? String { webView.customUserAgent = userAgent +"/Custom Agent" } } |
或使用牺牲UIWebView
1 | webView.customUserAgent = (UIWebView().stringByEvaluatingJavaScript(from:"navigator.userAgent") ??"") +"/Custom agent" |
旧答案:
如我的评论中所述,您可以使用此处所述的相同方法:在UIWebView(iPhone SDK)中更改用户代理
现在,如果要获取用户代理,则需要具有WKWebView的实例并在其上评估此javascript:
1 | navigator.userAgent |
问题是,如果在实例化WKWebView之后设置自定义用户代理,则将始终获得相同的用户代理。要解决此问题,您必须重新实例化Web视图。这是一个示例,看起来如何:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | self.wkWebView = [[WKWebView alloc] initWithFrame:self.view.bounds]; __weak typeof(self) weakSelf = self; [self.wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) { __strong typeof(weakSelf) strongSelf = weakSelf; NSString *userAgent = result; NSString *newUserAgent = [userAgent stringByAppendingString:@" Appended Custom User Agent"]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:newUserAgent, @"UserAgent", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; strongSelf.wkWebView = [[WKWebView alloc] initWithFrame:strongSelf.view.bounds]; // After this point the web view will use a custom appended user agent [strongSelf.wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) { NSLog(@"%@", result); }]; }]; |
上面的代码将记录:
1 | Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B411 Appended Custom User Agent |
另类
通过使用"牺牲" UIWebView,这可以变得更加简单,因为它可以同步评估javascript。
1 2 3 4 5 6 7 8 9 10 | UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds]; NSString *userAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]; NSString *newUserAgent = [userAgent stringByAppendingString:@" Appended Custom User Agent"]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:newUserAgent, @"UserAgent", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; self.wkWebView = [[WKWebView alloc] initWithFrame:self.view.bounds]; [self.wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) { NSLog(@"%@", result); }]; |
哪个日志相同:
1 | Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B411 Appended Custom User Agent |
现在,UIWebView和WKWebView使用相同的用户代理,但是如果将来发生这种情况,这种方法可能会引起问题。
自定义用户代理
要设置自定义用户代理,可以使用
1 2 3 | let webConfiguration = WKWebViewConfiguration() let webView = WKWebView(frame: .zero, configuration: webConfiguration) webView.customUserAgent ="ExampleApp/1.0 (iPhone)" |
可用:iOS 9+
附加到默认的用户代理
要在默认用户代理的和处添加自定义字符串,可以使用
1 2 3 | let webConfiguration = WKWebViewConfiguration() webConfiguration.applicationNameForUserAgent ="ExampleApp/1.0 (iPhone)" let webView = WKWebView(frame: .zero, configuration: webConfiguration) |
然后看起来像这样:
1 2 3 | Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7 (KHTML, like Gecko) ExampleApp/1.0 (iPhone) ^^^^^^^^^^^^^^^^^^^^^^^ |
可用:iOS 9+
1 2 | let userAgentValue ="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4" webView.customUserAgent = userAgentValue |
请注意那些尝试使用Storyboard或Interface Builder进行操作的人:不幸的是,Xcode当前不支持在Storyboards(Xcode版本8.3.2)中使用
1 | UserDefaults.standard.register(defaults: ["UserAgent": userAgentValue]) |
WKWebView中的默认User-Agent为
1 | Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) |
您可以自定义WKWebView用户代理
1 | webView.customUserAgent ="zgpeace User-Agent" |
我为WKWebView编写了一个演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | func requestWebViewAgent() { print("requestWebViewAgent") let webView = WKWebView() webView.evaluateJavaScript("navigator.userAgent") { (userAgent, error) in if let ua = userAgent { print("default WebView User-Agent > \\(ua)") } // customize User-Agent webView.customUserAgent ="zgpeace User-Agent" } } |
警告:当释放webView时,webView中的" User-Agent"为零。您可以将webView对象设置为属性以保留webView。
NSURLSession默认发送用户代理。
默认为User-Agent样式。
1 | "User-Agent" ="UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0"; |
我们可以自定义用户代理。
1 2 | let config = URLSessionConfiguration.default config.httpAdditionalHeaders = ["User-Agent":"zgpeace User-Agent"] |
我在下面为URLSession编写了一个演示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | func requestUrlSessionAgent() { print("requestUrlSessionAgent") let config = URLSessionConfiguration.default // default User-Agent:"User-Agent" ="UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0"; // custom User-Agent config.httpAdditionalHeaders = ["User-Agent":"zgpeace User-Agent"] let session = URLSession(configuration: config) let url = URL(string:"https://httpbin.org/anything")! var request = URLRequest(url: url) request.httpMethod ="GET" let task = session.dataTask(with: url) { data, response, error in // ensure there is no error for this HTTP response guard error == nil else { print ("error: \\(error!)") return } // ensure there is data returned from this HTTP response guard let content = data else { print("No data") return } // serialise the data / NSData object into Dictionary [String : Any] guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else { print("Not containing JSON") return } print("gotten json response dictionary is \ \\(json)") // update UI using the response here } // execute the HTTP request task.resume() } |
NSURLConnection默认情况下发送User-Agent。
默认为User-Agent样式。
1 | "User-Agent" ="UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0"; |
我们可以自定义用户代理。
1 | urlRequest.setValue("URLConnection zgpeace User-Agent", forHTTPHeaderField:"User-Agent") |
我在下面为URLConnection编写了一个演示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | func requestUrlConnectionUserAgent() { print("requestUrlConnectionUserAgent") let url = URL(string:"https://httpbin.org/anything")! var urlRequest = URLRequest(url: url) urlRequest.httpMethod ="GET" // default User-Agent:"User-Agent" ="UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0"; urlRequest.setValue("URLConnection zgpeace User-Agent", forHTTPHeaderField:"User-Agent") NSURLConnection.sendAsynchronousRequest(urlRequest, queue: OperationQueue.main) { (response, data, error) in // ensure there is no error for this HTTP response guard error == nil else { print ("error: \\(error!)") return } // ensure there is data returned from this HTTP response guard let content = data else { print("No data") return } // serialise the data / NSData object into Dictionary [String : Any] guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else { print("Not containing JSON") return } print("gotten json response dictionary is \ \\(json)") // update UI using the response here } } |
github中的演示:
https://github.com/zgpeace/UserAgentDemo.git
在我的迅速3情况下,我需要使用自定义userAgent的整个应用程序,这是我在AppDelegate中的解决方案。在这里使用UIWebview是因为我不需要设置WKWebViewConfiguration,因为我只需要userAgent字符串
1 2 3 4 5 6 7 8 | fileprivate func setupGlobalWebviewUserAgent() { let webview = UIWebView() var newUserAgent = webview.stringByEvaluatingJavaScript(from:"navigator.userAgent") newUserAgent = newUserAgent?.appending("custom user agent") let dictionary = Dictionary(dictionaryLiteral: ("UserAgent", newUserAgent)) UserDefaults.standard.register(defaults: dictionary) } |