V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fengleidongxi
V2EX  ›  Android

关于网站检测浏览器 UA

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

    已强制开启浏览器调试,并更改了浏览器 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   ·   我们的愿景   ·   实用小工具   ·   1490 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 17:21 · PVG 01:21 · LAX 10:21 · JFK 13:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.