UA信息

转:

UA信息

 

 对于WAP网站来说我们知道手机的机型适配变得异常重要。在讨论UA前我们看下典型的几个UA的例子:

 

1)SCH-M609/1.0 POLARIS/5.30.WAP CTC/1.0

2)Mozilla/5.0 (LG-KV755/CH755V05;U;REX/1.0;BREW/3.1.5;240*320;CTC/1.0) Polaris/6.15

3)K-Touch/Windows CE 5.2,Pocket PC Profile/MIDP-2.0  Configuration/CLDC-1.1 /1.0

 

第一个UA我们通过第一个字串SCH-M609可以知道该手机为三星M609;而第二个UA说明这个浏览器兼容Mozilla 5.0标准,而能识别机型的特征字串LG-KV755并不在UA前面几个字节,这里知道用户的机型为LG KV755。而第三个UA我们只能从K-Touch知道这个是天宇朗通的某款手机,并且操作系统为Windows CE 5.2,不过我们还是无法知道具体是哪个机型。

 

前面两个UA是我们需要程序识别的,而第三个UA要求程序来识别过于苛刻。即便是为了识别以上两个UA我们面临一个非常大的问题是,从第一、第二两个例子当中我们可以看出,我们无法简单的取第一个斜杠前的数据作为判断的依据。当然我们可以考虑全字符串匹配,但这面临着另外一个问题,尤其针对智能机来说,用户可以安装不同的浏览器,或者这些机器出厂的时候就带了多个浏览器。

 

下图是我们在WAP网关取到的一些天语E61机型留下的UA数据,例子中我们就选取了个别数据作为说明,实际E61的UA可能多达十几种。我们可以看到基本上如果按全字符串匹配会需要维护非常庞大的数据,并且随着浏览器版本升级,这样的数据会越来越多。

 

在WAP网关发现天语E61的UA
 
Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11) TY-E61/V2116 MSIEMobile/6.0 CTC/1.0
 
Mozilla/5.0 (TY-E61/810118_2190_V3018;U;Windows Mobile/6.1;Profile/MIDP-2.0
 
Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 8.12; MSIEMobile 6.0) TY-E61/V0809 MSIEMobile/6.0 CTC/1.0
 
Mozilla/5.0_(TY-E61/V2116;U;Windows Mobile/6.1;Profile/MIDP-2.0_Configuration/CLDC1.1;;CTC/2.0)_OPERA/9.51
 
Mozilla/5.0_(TY-E61/V2111;U;WindowsMobile/6.1;Profile/MIDP-2.0_Configuration/CLDC1.1;;CTC/2.0)_OPERA/9.51-
 
……………………..
 


   当然你觉得这可能是智能机由于安装软件方便,是导致一款机型,不同UA众多的主要原因,不是个例。不过我们同样可以取到三星的非智能手机F539这款机器的UA也接近10种。

 

在WAP网关发现三星F539的UA
 
SCH-F539 Infraware/5.30.CU (GUI)/WAP2.0 Profile/MIDP-2.0 Configuration/CLDC-1.1
 
SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1
 
SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,Profile/MIDP-2.0 Configuration/CLDC-1.1,UNTRUSTED/1.0
 
SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,UNTRUSTED/1.0
 
SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,Nokia6610/1.0 (5.52) Profile/MIDP-1.0 Configuration/CLDC-1.0,UNTRUSTED/1.0
 
SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,Profile/MIDP-2.0 Configuration/CLDC-1.0,UNTRUSTED/1.0
 
SCH-F539/F539CG17 POLARIS/5.30 CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1
 
SCH-F539/F539CG17 POLARIS/5.30 CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,Profile/MIDP-2.0 Configuration/CLDC-1.1,UNTRUSTED/1.0
 
SCH-F539/F539CG17 POLARIS/5.30 CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1,UNTRUSTED/1.0
 
……………………..
 

 

   所以我们需要考虑使用某种算法来识别机型,可以明显看出TY-E61,和SCH-F539是最识别机型的最重要数据。我们可能会考虑是否可以用正则表达式进行匹配。不过熟悉程序开发的人很快会想到如果有1000款手机,1000个正则表达式下来,是相当耗费资源的事情。


   解决办法其实也相当简单,我们需要的是找出机型的特征串,整理出来如下图表格的数据:

 

手机型号
 特征串
 生产厂家
 操作系统
 分辨率
 上市时间
 
三星F309
 SCH-F309
 三星
 REX
 176×220
 200812
 
三星F319
 SCH-F319
 三星
 REX
 128×160
 200511
 
三星F539
 SCH-F539
 三星
 REX
 240×320
 200904
 
天语E61
 TY-E61
 天语
 Windows Mobile
 240×320
 200905
 
酷派N900+
 YL-Coolpad_N900+
 宇龙酷派
 Windows CE
 320×480
 200912
 
酷派N900C
 YL-COOLPAD_N900C
 宇龙酷派
 Windows CE
 320×480
 200911
 
华为C7100
 HUAWEI-C7100
 华为
 REX
 240×320
 200809
 
华为C7168
 HUAWEI-C7168
 华为
 REX
 176×220
 200609
 
华为C7188
 HUAWEI-C7188
 华为
 REX
 240×320
 200712
 
华为C7189
 HUAWEI-C7189
 华为
 REX
 240×320
 201004
 
华为C7200
 HUAWEI-C7200
 华为
 REX
 240×320
 200802
 

 

  1) 我们可以考虑将特征串作为某个Hash的key,而Value设置为手机机型,以上数据转换为

Hash:Mobile {

"SCH-F309"  =>  "三星F309";

"SCH-F319"  =>  "三星F319";

"SCH-F539"  =>  "三星F539";

"TY-E61"  =>  "天语E61";

"YL-Coolpad_N900+"  =>  "酷派N900+";

"YL-COOLPAD_N900C"  =>  "酷派N900C";

"HUAWEI-C7100"  =>  "华为C7100";

"HUAWEI-C7168"  =>  "华为C7168";

"HUAWEI-C7188"  =>  "华为C7188";

"HUAWEI-C7189"  =>  "华为C7189";

"HUAWEI-C7200"  =>  "华为C7200";

}

 

2)将这样的数据可以使用Java Servlet,或者MemCached预先放入内存里面。这个时候就可以对于用户访问WAP网站的UA进行判断。

比如以下UA:

SCH-F539/1.0 POLARIS/5.30.WAP CTC/1.0 Profile/MIDP-2.1 Configuration/CLDC-1.1

 我们可以使用空格,斜杠等作为分隔符将以上UA拆分成字符串数组为

{“SCH-F539”,“1.0”,“POLARIS”,“5.30.WAP”,“CTC”,“1.0”,“Profile”,“MIDP-2.1”,“Configuration”,“CLDC-1.1”}

 

3)这些字串分别作为Key到内存Hash里面取值,我们会发现仅仅字串“SCH-F539”会取到数据为:“三星F539”,而其他Key取到的都为Null;这样我们就可以判断机型为:三星F539

 

4 ) 同样的我们也可以将生产厂家,操作系统,分辨率,上市日期这些值作为内存Hash,这样我们就可以取到其他该机型的其他必要数据。

 

 

 

User-Agent(简称UA)HTTP请求头部用来标识客户端信息的字符串, 包括操作系统, 浏览器等信息. 为了建立手机客户端的信息数据库, 需要从手机的http请求中取到这一字符串.


iPhone中取到UA信息的方法如下:

1. 利用浏览器控件UIWebView建立一个http请求

2. 在请求建立的期间, 建立一个新的事件循环用来判断UA信息是否已经建立

3. 在发送http请求之前截获UA信息, 并且取消这一http请求;)


获取iPhone UA的代码如下:

 

  1. UIWebView *_webView;
  2. NSString *userAgent;

 

  1. - (void)createHttpRequest {
  2. _webView = [[UIWebView alloc] init];
  3. _webView.delegate=self;
  4. [_webView loadRequest:[NSURLRequest requestWithURL:
  5. [NSURL URLWithString:@"http://www.google.com"]]];
  6. NSLog(@"%@", [self userAgentString]);
  7. [_webViewrelease];
  8. }
  9. -(NSString *)userAgentString
  10. {
  11. while (self.userAgent ==nil
  12. {
  13. NSLog(@"%@", @"in while");
  14. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
  15. }
  16. return self.userAgent;
  17. }
  18. -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
  19. {
  20. if (webView ==_webView) {
  21. self.userAgent = [requestvalueForHTTPHeaderField:@"User-Agent"];
  22. // Return no, we don't care about executing an actual request.
  23. returnNO;
  24. }
  25. return YES;
  26. }
  27. - (void)dealloc {
  28. [userAgentrelease];
  29.     [superdealloc];
  30. }


程序在iPhone4.1模拟器中运行结果如下:

2010-12-21 12:52:38.302 UATest[6722:207] in while

2010-12-21 12:52:38.305 UATest[6722:207] in while

2010-12-21 12:52:38.307 UATest[6722:207] in while

2010-12-21 12:52:38.307 UATest[6722:207] in while

2010-12-21 12:52:38.308 UATest[6722:207] in while

2010-12-21 12:52:38.309 UATest[6722:207] in while

2010-12-21 12:52:38.312 UATest[6722:207] Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/8B117



Android中获取UA的方法如下:

1. 建立一个WebView可以从中得到WebSettings

2. WebSettings这个类有个getUAString函数


Android中获取UA的代码如下:

 

1    WebViewwebview;

2    webview new WebView(this);

3     webview.layout(0, 0, 0, 0);

4     WebSettings settings = webview.getSettings();

5     String ua = settings.getUserAgentString();

6      Log.i("UA", ua);

 


Nexus One手机中测试结果UA如下:

Mozilla/5.0 (Linux; U; Android 2.2; zh-cnNexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1


getUserAgent的源码如下:

991     public synchronized String getUserAgentString() {

992         if (DESKTOP_USERAGENT.equals(mUserAgent||

993                 IPHONE_USERAGENT.equals(mUserAgent||

994                 !mUseDefaultUserAgent) {

995             return mUserAgent;

996         }

997 

998         boolean doPostSync false;

999         synchronized(sLockForLocaleSettings) {

1000            Locale currentLocale Locale.getDefault();

1001            if (!sLocale.equals(currentLocale)) {

1002                sLocale currentLocale;

1003                mUserAgent getCurrentUserAgent();

1004                mAcceptLanguage getCurrentAcceptLanguage();

1005                doPostSync true;

1006            }

1007        }

1008        if (doPostSync) {

1009            postSync();

1010        }

1011        return mUserAgent;

1012    }


296     private synchronized String getCurrentUserAgent() {

297         Locale locale;

298         synchronized(sLockForLocaleSettings) {

299             locale sLocale;

300         }

301         StringBuffer buffer new StringBuffer();

302         // Add version

303         final String version Build.VERSION.RELEASE;

304         if (version.length() 0) {

305             buffer.append(version);

306         else {

307             // default to "1.0"

308             buffer.append("1.0");

309          

310         buffer.append("; ");

311         final String language locale.getLanguage();

312         if (language != null{

313             buffer.append(language.toLowerCase());

314             final String country locale.getCountry();

315             if (country != null{

316                 buffer.append("-");

317                 buffer.append(country.toLowerCase());

318             }

319         else {

320             // default to "en"

321             buffer.append("en");

322         }

323         

324         final String model Build.MODEL;

325         if (model.length() 0) {

326             buffer.append("; ");

327             buffer.append(model);

328         }

329         final String id Build.ID;

330         if (id.length() 0) {

331             buffer.append(Build/");

332             buffer.append(id);

333         }

334         final String base mContext.getResources().getText(

335                 com.android.internal.R.string.web_user_agent).toString();

336         return String.format(base, buffer);

337     }


和源码比较后可以看出, androidUA字符串包括: 基本信息+版本号+国家语言+型号+型号ID+浏览器信息

其中,

 基本信息:

 "Mozilla/5.0 (Linux; U;Android "

 浏览器信息:

 AppleWebKit/533.1 (KHTML, likeGecko) Version/4.0Mobile Safari/533.1

 这两部分并没有源码可寻, 说明android的开源并不彻底.


 参考资料http://blog.sallarp.com/iphone-ipad-get-user-agent-for-uiwebview/

 一个android在线源码的地址http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/webkit/WebSettings.java#WebSettings.getUserAgentString()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值