受欢迎的博客标签

根据请求头(request header)来判断是否是手机访问及手机操作系统

Published

Table of content

How to Detect mobile device in ASP.NET Core

How to Detect mobile device in java

nginx通过UA来判断是否来自移动端访问 

网页纯客户端js实现方式(https://www.cnblogs.com/doseoer/p/4390002.html

 

How to Detect mobile device in java

我们现在做的项目,移动端和PC端网站访问的是同一套接口,那么如何在接口中区分是手机访问还是PC短访问呢?

核心思想:根据请求头(request header)来判断,如何请求没有header或伪造user agent则无法判断.

先看一些user agent的实例:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) (Engine, like URL) Mobile/12B440 MicroMessenger/6.0.1 NetType/3G+

 

Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI

 

Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.5.489 U3/0.8.0 Mobile Safari/533.1

 

Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10

 

Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; HUAWEI G700-U00 Build/HuaweiG700-U00) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 V1_AND_SQ_5.3.1_196_YYB_D QQ/5.3.1.2335 NetType/WIFI

 

Mozilla/5.0 (Linux; U; Android 4.0.4; zh-cn; HS-EG906 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/5.3.1.67_r745169.462

 

Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-Manager Mobile Safari/537.36



 

以下是我封装的一套方法

ClientOsInfo 是用于保存访问设备信息的,结构如下(省略getter,setter):

Java代码  
    public class ClientOsInfo {  
        /*** 
         * 比如 Android_3.0 
         */  
        private String osTypeVersion;  
        /*** 
         * Pad或Phone 
         */  
        private String deviceType;  
        /*** 
         * os type 
         */  
        private String osType;  
        /*** 
         * 只是版本号,例如"4.1.1" 
         */  
        private String version;  
        private String userAgent;  
    /*** 
         * 是否是移动设备 
         * @return 
         */  
        public boolean isMobile(){  
            return (!ValueWidget.isNullOrEmpty(this.deviceType));  
        }  
    }  
  1.  

 核心方法:

Java代码  
    /*** 
     * 当移动端(手机或Pad)访问网页时获取移动端操作系统信息 
     * @param request 
     * @return 
     */  
    public static ClientOsInfo getMobileOsInfo(HttpServletRequest request){  
        String userAgent=request.getHeader("user-agent");  
        if(ValueWidget.isNullOrEmpty(userAgent)){  
            userAgent=request.getHeader("User-Agent");  
        }  
        ClientOsInfo info= HeaderUtil.getMobilOS(userAgent);  
        info.setUserAgent(userAgent);  
        return info;  
    }  
  1.  

 

核心工具类:用于解析user agent

Java代码  
package com.common.util;  
  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
  
import com.common.bean.ClientOsInfo;  
import com.string.widget.util.ValueWidget;  
  
/*** 
 *  
 * @author huangwei 
 * @since 2013-08-15 
 */  
public class HeaderUtil {  
    public static final String OSTYPE_ANDROID="Android";  
    public static final String OSTYPE_IOS="Ios";  
    public static final String OSTYPE_WP="WINDOWS PHONE";  
    public static final String OSTYPE_BLACKBERRY="BLACKBERRY";  
    /*** 
     * pad 
     */  
    public static final String DEVICE_TYPE_PAD="Pad";  
    /*** 
     * 手机 
     */  
    public static final String DEVICE_TYPE_PHONE="Phone";  
  
  
    /*** 
     * 校验渠道终端版本号是否合法,eg:0.0.0.3 
     *  
     * @param clientVersion 
     * @return true-->合法 ;false-->非法 
     */  
    public static boolean verifyClientVersion(String clientVersion) {  
        boolean result = Pattern.matches("[\d\.]+", clientVersion);  
        if (result) {  
            result = Pattern.matches("^\d\.\d\.\d\.\d$", clientVersion);  
            return result;  
        } else {  
            return false;  
        }  
    }  
      
    /** 
     * 根据useragent和手机厂商查手机型号 
     *  
     * @param UA 
     * @param vendor 
     * @return 
     */  
    public static String getMobModel(String UA, String operatingSystem) {  
        if (UA == null) {  
            return null;  
        }  
        // 存放正则表达式  
        String rex = "";  
        // 苹果产品  
        if (operatingSystem.indexOf("IOS") != -1) {  
            if (UA.indexOf("IPAD") != -1) {// 判断是否为ipad  
                return "IPAD";  
            }  
            if (UA.indexOf("IPOD") != -1) {// 判断是否为ipod  
                return "IPOD";  
            }  
            if (UA.indexOf("IPONE") != -1) {// 判断是否为ipone  
                return "IPONE";  
            }  
            return "IOS DEVICE";  
  
        }  
        // 安卓系统产品  
        if (operatingSystem.indexOf("ANDROID") != -1) {  
            String re = "BUILD";  
            rex = ".*" + ";" + "(.*)" + re;  
            Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
            Matcher m = p.matcher(UA);  
            boolean rs = m.find();  
            if (rs) {  
                System.out.println("Mobil Model is" + m.group(1));  
                return m.group(1);  
            }  
        }  
        return null;  
    }  
  
    /** 
     * 判断手机的操作系统 IOS/android/windows phone/BlackBerry 
     *  
     * @param UA 
     * @return 
     */  
    public static ClientOsInfo getMobilOS(String UA) {  
        UA=UA.toUpperCase();  
        if (UA == null) {  
            return null;  
        }  
        ClientOsInfo osInfo=new  ClientOsInfo();  
        // 存放正则表达式  
        String rex = "";  
        // IOS 判断字符串  
        String iosString = " LIKE MAC OS X";  
        if (UA.indexOf(iosString) != -1) {  
            if(isMatch(UA, "\([\s]*iPhone[\s]*;", Pattern.CASE_INSENSITIVE)){  
                osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
            }else if(isMatch(UA, "\([\s]*iPad[\s]*;", Pattern.CASE_INSENSITIVE)){  
                osInfo.setDeviceType(DEVICE_TYPE_PAD);  
            }  
            rex = ".*" + "[\s]+(\d[_\d]*)" + iosString;  
            Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
            Matcher m = p.matcher(UA);  
            boolean rs = m.find();  
            if (rs) {  
                String osVersion= m.group(1).replace("_", ".");  
                osInfo.setVersion(osVersion);  
//              System.out.println("Mobil OS is" + " IOS" +osVersion);  
                osInfo.setOsTypeVersion(OSTYPE_IOS+"_" + osVersion);  
            }else{  
                System.out.println("IOS");  
                osInfo.setOsTypeVersion(OSTYPE_IOS);  
            }  
            osInfo.setOsType(OSTYPE_IOS);  
            return osInfo;  
        }  
        // Android 判断  
        String androidString = "ANDROID";  
        if (UA.indexOf(androidString) != -1) {  
            if(isMatch(UA, "\bMobi", Pattern.CASE_INSENSITIVE)){  
                osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
            }else {  
                osInfo.setDeviceType(DEVICE_TYPE_PAD);  
            }  
            rex = ".*" + androidString + "[\s]*(\d*[\._\d]*)";  
            Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
            Matcher m = p.matcher(UA);  
            boolean rs = m.find();  
            if (rs) {  
                String version=m.group(1).replace("_", ".");  
                osInfo.setVersion(version);  
                System.out.println("Mobil OS is " + OSTYPE_ANDROID + version);  
                osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_" + version);  
            }else{  
                System.out.println("Android");  
                osInfo.setOsTypeVersion(OSTYPE_ANDROID);  
            }  
            osInfo.setOsType(OSTYPE_ANDROID);  
            return osInfo;  
        }  
        // windows phone 判断  
        String wpString = "WINDOWS PHONE";  
        if (UA.indexOf(wpString) != -1) {  
            rex = ".*" + wpString + "[\s]*[OS\s]*([\d][\.\d]*)";  
            Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
            Matcher m = p.matcher(UA);  
            boolean rs = m.find();  
            if (rs) {  
                System.out.println("Mobil OS is " + OSTYPE_WP + m.group(1));  
                String version=m.group(1);  
                osInfo.setVersion(version);  
                osInfo.setOsTypeVersion(OSTYPE_WP+"_" + version);  
            }else{  
                System.out.println("WINDOWS PHONE");  
                osInfo.setOsTypeVersion(OSTYPE_WP);  
            }  
            osInfo.setOsType(OSTYPE_WP);  
            return osInfo;  
        }  
        // BlackBerry 黑莓系统判断  
        String bbString = "BLACKBERRY";  
        if (UA.indexOf(bbString) != -1) {  
            rex = ".*" + bbString + "[\s]*([\d]*)";  
            Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
            Matcher m = p.matcher(UA);  
            boolean rs = m.find();  
            if (rs) {  
                System.out.println("Mobil OS is" + " BLACKBERRY " + m.group(1));  
                String version=m.group(1);  
                osInfo.setVersion(version);  
                osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY+"_" + version);  
            }else{  
                System.out.println("BLACKBERRY");  
                osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY);  
            }  
            osInfo.setOsType(OSTYPE_BLACKBERRY);  
            return osInfo;  
        }  
        if(UA.contains("LINUX")){//android  
            if(isMatch(UA, "\bMobi", Pattern.CASE_INSENSITIVE)){  
                osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
            }else {  
                osInfo.setDeviceType(DEVICE_TYPE_PAD);  
            }  
              
             Pattern p = Pattern.compile("U;\s*(Adr[\s]*)?(\d[\.\d]*\d)[\s]*;",Pattern.CASE_INSENSITIVE);  
                Matcher m = p.matcher(UA);  
                boolean result = m.find();  
                String find_result = null;  
                if (result)  
                {  
                    find_result = m.group(2);  
                }  
                if(ValueWidget.isNullOrEmpty(find_result)){  
                    osInfo.setOsTypeVersion(OSTYPE_ANDROID);  
                    return osInfo;  
                }else{  
                    osInfo.setVersion(find_result);  
                    osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_"+find_result);  
                    return osInfo;  
                }  
        }  
          
        //UCWEB/2.0 (iOS; U; iPh OS 4_3_2; zh-CN; iPh4)  
        if(UA.matches(".*((IOS)|(iPAD)).*(IPH).*")){  
            if(isMatch(UA, "[\s]*iPh[\s]*", Pattern.CASE_INSENSITIVE)){  
                osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
            }else {  
                osInfo.setDeviceType(DEVICE_TYPE_PAD);  
            }  
             Pattern p = Pattern.compile("U;\s*(IPH[\s]*)?(OS[\s]*)?(\d[\._\d]*\d)[\s]*;",Pattern.CASE_INSENSITIVE);  
                Matcher m = p.matcher(UA);  
                boolean result = m.find();  
                String find_result = null;  
                if (result)  
                {  
                    find_result = m.group(3);  
                }  
                if(ValueWidget.isNullOrEmpty(find_result)){  
                    osInfo.setOsTypeVersion(OSTYPE_IOS);  
                    osInfo.setOsType(OSTYPE_IOS);  
                    return osInfo;  
                }else{  
                    String version=find_result.replace("_", ".");  
                    osInfo.setVersion(version);  
                    osInfo.setOsTypeVersion(OSTYPE_IOS+"_"+version);  
                    osInfo.setOsType(OSTYPE_IOS);  
                    return osInfo;  
                }  
        }  
        return osInfo;  
    }  
    public static boolean isMatch(String source,String regx,int flags){  
        Pattern p = Pattern.compile(regx,flags);  
        Matcher m = p.matcher(source);  
        boolean result = m.find();  
        return result;  
    }  
  
} 
  1.  

 

应用场景:

 

通过user agent判断是否是手机

Java代码  
/*** 
     * 判断是否是手机(移动端) 
     * @param userAgent 
     * @return 
     */  
    public static boolean isMobile(String userAgent)  
    {  
        userAgent=userAgent.toLowerCase();  
        String []mobile_agents = {"240x320","acer","acoon","acs-","abacho","ahong","airness","alcatel","amoi","android","anywhereyougo.com","applewebkit/525","applewebkit/532","asus","audio","au-mic","avantogo","becker","benq","bilbo","bird","blackberry","blazer","bleu","cdm-","compal","coolpad","danger","dbtel","dopod","elaine","eric","etouch","fly ","fly_","fly-","go.web","goodaccess","gradiente","grundig","haier","hedy","hitachi","htc","huawei","hutchison","inno","ipad","ipaq","ipod","jbrowser","kddi","kgt","kwc","lenovo","lg ","lg2","lg3","lg4","lg5","lg7","lg8","lg9","lg-","lge-","lge9","longcos","maemo","mercator","meridian","micromax","midp","mini","mitsu","mmm","mmp","mobi","mot-","moto","nec-","netfront","newgen","nexian","nf-browser","nintendo","nitro","nokia","nook","novarra","obigo","palm","panasonic","pantech","philips","phone","pg-","playstation","pocket","pt-","qc-","qtek","rover","sagem","sama","samu","sanyo","samsung","sch-","scooter","sec-","sendo","sgh-","sharp","siemens","sie-","softbank","sony","spice","sprint","spv","symbian","tablet","talkabout","tcl-","teleca","telit","tianyu","tim-","toshiba","tsm","up.browser","utec","utstar","verykool","virgin","vk-","voda","voxtel","vx","wap","wellco","wig browser","wii","windows ce","wireless","xda","xde","zte"};  
        boolean is_mobile = false;  
        for (String device : mobile_agents) {  
            if(userAgent.contains(device)){  
                is_mobile=true;  
                break;  
            }  
        }  
        return is_mobile;  
    } 
  1.  

 测试代码:

Java代码
@Test  
    public void test_userAgent()  
    {  
        String userAgent="Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI";  
        System.out.println(HeaderUtil.isMobile(userAgent));  
          
        userAgent="Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10";  
        System.out.println(HeaderUtil.isMobile(userAgent));  
    } 
  1.  

 

 

Useful links

1.How to Detect mobile device in ASP.NET Core?

https://stackoverflow.com/questions/41295969/detect-mobile-device-in-asp-net-core

2.Device detection .NET CORE

ASP.NET Core Detection service components for identifying details about client device, browser, engine, platform, & crawler

https://github.com/wangkanai/Detection