获取以及自定义User-Agent在URLSession, NSURLConnection, WKWebView iOS

说明

User-Agent是HTTP请求中header相当重要的信息,告诉接收方这个请求是从哪里来的。比如从ZgpeaceApp发个请求到服务器,服务器就通过User-Agent知道是从ZgpeaceApp过来的。服务端response data到App,User-Agent就会带上服务器的信息,比如AWS。

本文记录iOS 默认的User-Agent, 和如何定制化User-Agent.
实际上App发HTTP请求,会有两种情况:

  1. native 通过URLSession发HTTP请求
  2. 通过WKWebView发HTTP请求
  3. native 通过URLConnection发HTTP请求

注意:User-Agent在WKWebView获取会得到nil空值,这是因为WebView被释放了,把WKWebView对象定义为属性就好,下面有例子。

1. NSURLSession的User-Agent

NSURLSession默认的User-Agent格式如下.

"User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";

格式定义如下:

$(CFBundleName)/$(CFBundleVersion) CFNetwork/808.3 Darwin/16.3.0

可以自定义User-Agent

let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "zgpeace User-Agent"]
I write a demo for URLSession in the below.

下面是URLSession例子

func requestUrlSessionAgent() {
     print("requestUrlSessionAgent")
//        let url = URL(string: "https://stackoverflow.com")
//        let url = URL(string: "https://user-agent.me")
     
     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 \n \(json)")
         // update UI using the response here
     }

     // execute the HTTP request
     task.resume()
     
 }

2. WKWebView的User-Agent

WKWebView 默认的User-Agent如下

Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X)

定制化WKWebView的User-Agent

webView.customUserAgent = "zgpeace User-Agent"

WKWebView获取User-Agent的例子

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被释放了,User-Agent就得到nil空值。解决这个问题,把webView定义为属性property就好。

3. NSURLConnection的User-Agent

NSURLConnection默认的User-Agent格式如下.

"User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";

格式定义如下:

$(CFBundleName)/$(CFBundleVersion) CFNetwork/808.3 Darwin/16.3.0

可以自定义User-Agent

urlRequest.setValue("URLConnection zgpeace User-Agent", forHTTPHeaderField: "User-Agent")

下面是URLConnection例子

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 \n \(json)")
        // update UI using the response here
    }

  }

例子下载

https://github.com/zgpeace/UserAgentDemo

参考

https://awesome-tips.gitbook.io/ios/webview/content

https://stackoverflow.com/questions/51356476/ios-12-wkwebview-set-customuseragent-not-work

https://stackoverflow.com/questions/36379347/does-nsurlsession-send-user-agent-automatically

https://stackoverflow.com/questions/8030550/what-http-user-agent-does-my-ios-program-advertise-itself-as

https://fluffy.es/nsurlsession-urlsession-tutorial/

发布了167 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/105063656