关于ios:在WKWebview中设置useragent

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字符串?


您会很高兴听到WKWebView刚刚在iOS 9OSX 10.11中获得了customUserAgent属性

例:

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使用相同的用户代理,但是如果将来发生这种情况,这种方法可能会引起问题。


自定义用户代理

要设置自定义用户代理,可以使用customUserAgent属性:

1
2
3
let webConfiguration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.customUserAgent ="ExampleApp/1.0 (iPhone)"

可用:iOS 9+

附加到默认的用户代理

要在默认用户代理的和处添加自定义字符串,可以使用applicationNameForUserAgent属性:

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+


WKWebView Swift 3示例:

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)中使用WKWebView,因此您必须在代码中手动添加Web视图。

UIWebView Swift 3示例:

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)
}