关于网站检测浏览器 UA - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fengleidongxi
V2EX    Android

关于网站检测浏览器 UA

  •  
  •   fengleidongxi 2018-02-14 18:27:27 +08:00 18162 次点击
    这是一个创建于 2798 天前的主题,其中的信息可能已经有所发展或是发生改变。

    已强制开启浏览器调试,并更改了浏览器 UA 和分辨率,操作系统 UA 也更改成了桌面,为什么有少数网站仍然能检测到用的是非桌面系统,并自动跳转到 WAP、移动版网页,他是究竟是怎么检测到的?

    第 1 条附言    2018-02-15 10:56:36 +08:00
    最新测试结果:

    用强制调试模式,修改 UA 和分辨率,网站跳转移动版。navigator.platform 返回:Linux armv8l。

    用浏览器自带的“请求桌面版网站”,网站顺利进入桌面版,并未跳转。navigator.platform 返回:Linux armv8l。

    上面两种模式,navigator.platform 返回值相同。

    现在应该研究“请求桌面版网站”除了修改 UA 和分辨率,还修改了什么?有没有办法用调试模式修改?

    不明白浏览器为什么要这样设计?
    第 2 条附言    2018-02-15 11:07:37 +08:00
    强制调试模式和浏览器自带的“请求桌面版网站”:UA、分辨率、platform、CPUClass、全部相同。
    41 条回复    2018-02-17 01:10:26 +08:00
    lany
        1
    lany  
       2018-02-14 19:33:30 +08:00 via Android
    分辨率?
    zhuanzh
        2
    zhuanzh  
       2018-02-14 19:46:50 +08:00 via Android
    我之前问过
    一个同学说其中一种方法是通过手机浏览器无法实现的 js 判定
    fengleidongxi
        3
    fengleidongxi  
    OP
       2018-02-14 21:32:25 +08:00
    @zhuanzh 能具体些吗?移动端和桌面内核相同,Javascript 应该也一样啊,怎么会无法实现?
    fengleidongxi
        4
    fengleidongxi  
    OP
       2018-02-14 21:33:08 +08:00
    @lany UA 和分辨率修改了,仍然能检测到
    mikii
        5
    mikii  
       2018-02-14 21:34:24 +08:00
    能说一下少数网站都有哪个吗,想看看
    gam2046
        6
    gam2046  
       2018-02-14 21:38:30 +08:00   2
    是不是这位大佬的锅?

    window.navigator.platform

    一般来说多数浏览器模拟其他平台并不会改变这个的返回值,至于原因,并不明确。
    fengleidongxi
        7
    fengleidongxi  
    OP
       2018-02-14 21:50:17 +08:00
    @mikii 具体名字我也没记,反正都是不常用的网站。但是,用浏览器自带请求桌面,是检测不到的,说明浏览器自带的不只是更改 UA 和分辨率
    fengleidongxi
        8
    fengleidongxi  
    OP
       2018-02-14 21:54:33 +08:00
    @gam2046 可以说下这个值怎么测试吗?
    gam2046
        9
    gam2046  
       2018-02-14 21:57:51 +08:00
    https://i.loli.net/2018/02/14/5a843fe068ced.jpg

    我这是 Chrome 开了模拟,很早以前我试过 Chrome 和 Firefox 表现结果是一样的,Firefox 许久没用过,不得而知现在是否一样。Win32/Win64 总不可能是移动设备吧?
    fengleidongxi
        10
    fengleidongxi  
    OP
       2018-02-14 22:35:15 +08:00
    @gam2046 多谢多谢,刚才我也测试了,的确是 navigator.platform 的原因,移动端检测到 Linux armv8l,而桌面检测到 win32。这个有办法改吗?
    gam2046
        11
    gam2046  
       2018-02-14 22:43:20 +08:00   4
    如果浏览器是可控的(如应用开发者,可以直接改变该行为),如果浏览器不可控,navigator.platform 本身是只读属性,因此原则上是不能改。

    但是由于 Javascript 的关系,其实只要在检测代码之前运行一段代码是可以改变该属性的返回值:

    Object.defineProperty(navigator,'platform',{get:function(){return 'Linux armv8l';}});

    如果是桌面端浏览器,可以通过各类插件或者 userscript 来在网页 Javascript 执行之前改变该值。但是同样网站也可以检测到你变更了默认行为,接下去其实是无休无止的小九九,没啥意思了。但是绝大多数网站应该并没有这种检查,因此只要在网站之前执行上面那段代码,就可以了。

    https://i.loli.net/2018/02/14/5a844a822a394.jpg
    fengleidongxi
        12
    fengleidongxi  
    OP
       2018-02-14 22:49:03 +08:00
    @gam2046 桌面这办法多的是,主要是移动端,不太好办,检测这个的网站确实是少之又少
    gam2046
        13
    gam2046  
       2018-02-14 23:04:15 +08:00
    @fengleidongxi 移动端,听说 Firefox 是支持插件的,你可以试试。由于我自己中 Google 毒颇深,所以没在移动端用过 Firefox。包括有一些第三方个人开发者的浏览器也是支持插件的,也可以尝试。如果这些都不行,其实就比较麻烦了,方法依然有,但实际上没有可操作性。

    比如可以移动设备上开 VPN 连接本地,并安装自签证书,以进行中间人攻击,劫持 http/https 请求。

    不过我并没有看到过有类似的软件,有这方面功能的都是开发工具,通常用于抓包,并没有篡改的功能。

    话说回来,其实网站想知道是否为移动平台,有挺多奇技淫巧。比如桌面端的浏览器通常都不支持 HLS,而移动端支持。又比如桌面端浏览器在使用过程中不会出现触屏事件( touchstart/touchend/touchmove ),而移动端不会数显鼠标相关事件( mousedown/mousemove/mouseup )。所以这个其实是看网站方愿意花多大力气来检测,只要想,总是有一些出其不意的点能查出来。
    crysislinux
        14
    crysislinux  
       2018-02-14 23:13:17 +08:00
    还有个办法,移动端主流的浏览器 100vh 和 100% body.innerHeight 值是不一样的,但是桌面端是一样的
    fengleidongxi
        15
    fengleidongxi  
    OP
       2018-02-14 23:34:51 +08:00
    @gam2046 刚才我又测试了一次,移动端更改 UA、分辨率,可以检测到假桌面,并跳转移动版。但用浏览器自带的"请求桌面网站“选项,网站并没有检测到是桌面,也没有跳转移动版,顺利进入桌面版网页。这就说明浏览器自带的"请求桌面网站“选项,所更改的不只是 UA 和分辨率,还有其他,就是不知道这个其他是什么?("请求桌面网站“选项也没有改变 navigator.platform )
    fengleidongxi
        16
    fengleidongxi  
    OP
       2018-02-14 23:39:44 +08:00
    @crysislinux 看来能检测的真不少
    iwtbauh
        17
    iwtbauh  
       2018-02-15 00:05:16 +08:00 via Android
    @fengleidongxi 看到前面就有点怀疑,现在一看果然不是 window.navigator.platform 的问题,毕竟这个返回的是 Linux armv8l,要是当作移动端了,用 arm 处理器的 Linux 用户岂不是得抗议

    @gam2046 桌面浏览器也可能会产生触摸屏事件,比如带触摸屏的一体机 /带触摸屏的笔记本。之前见过,环境是 chromium,Debian GNU/Linux 8,Xorg,驱动程序是 xserver-xorg-input-libinput ( evdev 驱动下没有产生触摸屏事件)和 chrome,Windows 7 ( Tablet PC )
    gam2046
        18
    gam2046  
       2018-02-15 00:20:51 +08:00
    @iwtbauh 没使用过带触控输入设备的桌面端设备。所以,这个没有发言权。

    按照这么说,Chrome 会根据计算机上的驱动程序来决定 Javascript runtime ?如果你那边有环境的下,试试看这段 Javascript 在你说的环境下,是否会返回 true。我以为这种 runtime 的差异是在浏览器编译时期决定的,桌面端浏览器使用触控设备也会触发 mousemove 这些事件。不过,这本来就是奇技淫巧,应该在大多数场景下,还是比较具有参考性的

    ('ontouchstart' in document.documentElement)
    nciyuan
        19
    nciyuan  
       2018-02-15 04:08:38 +08:00 via Android
    @gam2046 树莓派用户已经强烈反感某大厂的网站了!
    @fengleidongxi 我刚才在我的服务器上开了个 phpinfo 测试了一下,Chrome 就是改了 UA 啊,没改前是
    Mozilla/5.0 (Linux; Android 7.1.1; OD105 Build/NMF26F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36
    改之后是
    Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Safari/537.36
    一般正确的判断是检测 UA 中的 Chrome 后是否含有 Mobile
    有则跳转,无则继续
    nciyuan
        20
    nciyuan  
       2018-02-15 04:22:06 +08:00 via Android
    还有部分网站是指?也有可能不是用的检测,而是声明 X-UA-Compatible,是主动型的。当然还还还还还有一堆方法,比如检测 Flash,现在的浏览器全部自带,手机一个没有(Adobe Flash Player 曾经有 Android 版,但是停更了)。IE 和 Edge 也带 flash 哦。
    opengps
        21
    opengps  
       2018-02-15 08:40:08 +08:00 via Android
    git 上见过一个开源项目,最终为了区分浏览器,尤其是 360,专门调用了一个后台渲染工具开达到识别目的
    iwtbauh
        22
    iwtbauh  
       2018-02-15 09:01:43 +08:00
    @gam2046 是的,会返回 true,但要求 chromium 是用 GTK+3 编译的(太旧的 GTK+2 编译的版本是无法产生触摸屏事件的),使用 libinput 驱动( evdev 驱动将触摸屏设备当作产生绝对位置的“鼠标”处理了)
    $ ldd /usr/lib/chromium/chromium | grep gtk
    libgtk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
    有的驱动程序就是直接把触摸屏当成鼠标的,但如果就是当成触摸屏的话,Windows 7 的 chrome 应该也是会识别出触摸屏的,Windows 7 微软还专门提供了一组触摸屏的 API 用于这个,可惜我的 windows 触摸屏机器已经没了没法测试
    gam2046
        23
    gam2046  
       2018-02-15 09:52:27 +08:00
    @fengleidongxi #15,UserAgent 在 Javascript 上下文中与你发起 http 请求时在 Http Headers 中是不同的。前者可以通过我提供的代码来修改,那么在那个 Context 中获取到的就是被修改后的值,但是该修改并不会影响 Http Request 中的 UserAgent,这个值是由浏览器填充的,可以通过一些浏览器插件修改。而大多数浏览器自带的模拟,会同时修改 Javascript 与 Http Request 中的 Useragent。

    @nciyuan #20 Flash 其实现在误伤算是比较大了,因为虽然 Chrome/Firefox 都还没完全放弃 Flash,但是默认都是禁用的。需要用户侧手动允许。在用户没有手动允许的情况,环境都没有 Flash 是一样的。

    @iwtbauh #22 嗯,这个有意思。因为我发现 Chrome 的模拟模式,会自动填充这些触屏事件。所以我自己写了一个 User Script,是这样做的:

    document.documentElement.Ontouchstart=
    document.documentElement.Ontouchmove=
    document.documentElement.Ontouchend=
    document.documentElement.Ontouchcancel= function () { };

    ---

    其实原则上要检查是否移动端方法是挺多的,上面各位大佬提到的 platform/flash/touch event/屏幕分辨率等等,综合判断下来应该还是比较准确的。
    grantonzhuang
        24
    grantonzhuang  
       2018-02-15 10:14:52 +08:00 via Android
    @gam2046 anyproxy 可以一试,有篡改的功能
    Telegram
        25
    Telegram  
       2018-02-15 10:41:23 +08:00 via iPhone
    这个问题我也一直想知道
    fengleidongxi
        26
    fengleidongxi  
    OP
       2018-02-15 10:58:07 +08:00
    @iwtbauh 确实是这样,我修改了主题,大家一起研究
    fengleidongxi
        27
    fengleidongxi  
    OP
       2018-02-15 11:10:17 +08:00
    @nciyuan 我补充了主题,大家一起研究研究
    fengleidongxi
        28
    fengleidongxi  
    OP
       2018-02-15 11:17:09 +08:00
    @gam2046 我修改了主题,你再看下。你的意思是我只是修改了 http 头信息,JS 中并未修改?你说的可能是对的,那有没有办法修改 JS 上下文中的 UA ?又如何测试 JS 上下文中的 UA ?
    gam2046
        29
    gam2046  
       2018-02-15 11:28:07 +08:00
    @fengleidongxi #28

    你首先要明确你的网页跳转时服务端实现(返回 301/302 状态码)还是客户端实现( Javascript )的。

    服务端判断只能依赖 HTTP Request Headers 中的 UserAgent
    而客户端 Javascript 就有各显神通的方法了。

    最后,你把网址发出来不就好了么?看一眼什么都清楚了。靠意念猜题....有点过了。
    iwtbauh
        30
    iwtbauh  
       2018-02-15 11:42:44 +08:00 via Android
    @gam2046 是的,综合考虑的情况确实有很多东西可以暴露出差异。我再补充一个:拖拽事件( ondrag 等)手机浏览器( Android 版本 chrome 64 )不支持
    fengleidongxi
        31
    fengleidongxi  
    OP
       2018-02-15 11:59:49 +08:00
    @gam2046 主要通过调试模式达到和“请求桌面版网站”一样的效果,不知道有没有办法。你试试论坛用调试模式能进桌面版吗
    gam2046
        32
    gam2046  
       2018-02-15 12:54:15 +08:00   1
    @fengleidongxi V2EX 不就是根据 request headers 来判断设备类型的么?有啥黑科技?我这试了试改变这个值就返回的不同页面。
    fengleidongxi
        33
    fengleidongxi  
    OP
       2018-02-15 14:22:05 +08:00
    @gam2046 你再试试 espn 英文站,我发现这些网站都有一个共同点,桌面版和移动版网址是一样的,用跳转这个词并不恰当,因为直接进入的就是移动版或者桌面版,并不是先进入 www 网址的桌面版,瞬间跳转另一个网址移动版。

    但凡是先进入桌面版,瞬间跳转移动版的网站,用调试模式都能正常进入桌面版并不跳转,大多数网站都是这样的。
    gam2046
        34
    gam2046  
       2018-02-15 14:33:28 +08:00
    .....这就是响应式布局而已。与你的浏览器的宽高有关。无所谓桌面与移动端的区别。

    你在电脑上用浏览器打开,然后把浏览器宽度缩小,也能看到像手机上那么的界面了。连页面都不用刷新。

    仅此而已。

    新年快乐。我要去登机了。
    fengleidongxi
        35
    fengleidongxi  
    OP
       2018-02-15 14:48:37 +08:00
    @gam2046 好的,新年快乐,一路顺风!
    cosformula
        36
    cosformula  
       2018-02-15 14:53:44 +08:00 via Android   1
    响应式布局+1
    这些网站的移动端,桌面端都是一套代码,手动改变宽高就可以观察到变化,不需要判断。
    如果没有做响应式设计,一般是通过 ua 判断跳转哪个页面的。
    fengleidongxi
        37
    fengleidongxi  
    OP
       2018-02-15 14:55:36 +08:00
    txydhr
        38
    txydhr  
       2018-02-15 17:35:35 +08:00
    @nciyuan 现在桌面浏览器也有不少默认屏蔽 flash
    nciyuan
        39
    nciyuan  
       2018-02-16 09:06:09 +08:00 via Android
    @fengleidongxi 大多数符合 Google MD 标准的网页设计一次就可以,还有你点击请求桌面之后是重载一遍,自适应的根本不变 url 好吗

    还有各位
    想了一个点子,但没有实践过
    很久没有写独立 pc 网页了
    就是手机浏览器不可能有 pc 的鼠标悬停,而且不可能有鼠标指针滑动,手机都是点下去而且不可能有按住这个鼠标必有的动作。手机屏幕长按都是弹出什么选择啊,自由复制啊,或者工具栏的。还有 js 里好像能通过判断 keycode 判断左右按键,而手机绝对没有
    当然这些都属于被动检测,而且多少都有点缺点,大佬们还是大开脑洞吧

    这个是写按键精灵 /游戏蜂窝时候想到的

    只会 UA 因为懒 2333

    (当年 ie 时代我还脑洞过 ActiveX 检测法~ 2333)
    gearkey
        40
    gearkey  
       2018-02-16 17:37:21 +08:00 via Android
    @nciyuan 悬停是可以用长按+滑动模拟的,不然多级菜单就废了,,右键和拖动浏览器想支持的话是可以的吧,但没看到了
    nciyuan
        41
    nciyuan  
       2018-02-17 01:10:26 +08:00 via Android
    @gearkey 的确,不过这种方法也很不方便,比如 discuz 就是这样,但是电脑上应该是点击同时包含一个按下和弹起
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3166 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 12:13 PVG 20:13 LAX 05:13 JFK 08:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86