编辑寄语

轻型客户端设备检测

Dino Esposito

Dino Esposito创建设备友好网站有两个基本选项 — 创建单独的移动站点(m 站点)或返工站点,以便其可以智能地按当前屏幕大小和方向调整内容和行为。这两个策略并非是所有情况下的理想选择。因此,最有深刻见解的方法是经典的“取决于”方法。

m 站点方法有两个主要缺点。首先,所有设备在屏幕大小和其他物理功能方面各不相同(从智能手机、平板电脑和迷你平板电脑到较为老旧的手机、平板手机、可穿戴设备等)。您最终该如何实际定义“移动”?

几年前,拥有 m 站点更有意义,因为台式计算机与其他所有设备之间没有一个清晰的界限。现在,“其他所有设备”的领域充斥了如此多的选择,一个通用的统一移动站点已经完全不够用了。m 站点的第二个缺点是它需要用户导航到明确的 URL,通常是一些 m.yourserver.com。这不再是理想的解决方案并仅能作为临时性修补程序进行采用。

而另一种选择 — 响应式用户界面 — 也有问题存在。关键问题是您如何能够让网站进行响应?人们通常认为,响应式站点是采用响应式 Web 设计 (RWD) 构建的。RWD 是一种开发方法,其使用 CSS 媒体查询的浏览器实现来检测屏幕大小和方向,并允许您定义断点(实质上是一个像素宽度)以自动应用不同的 CSS。

实际效果很有吸引力。调整浏览器窗口大小并侵入这些视觉断点之一时,该站点的外观将发生更改以更好地利用可用空间。无需支付额外成本,内容就可根据用于访问该站点的任何全屏移动浏览器进行调整。RWD 与设备无关,并可针对现在以及将来推出的任何数量和类型的设备进行伸缩。

正如我在 2014 年 12 月专栏“响应式网站中的有效图像处理”(msdn.microsoft.com/magazine/dn857356) 中所述,设备无关性是 RWD 的优势也是劣势。如果您的客户对于您通过 RWD 实现的结果(主要是性能和可用性)感到满意,那么一切就绪。RWD 是您的孩子并且您已大功告成。

RWD 通常可以和站点配合良好,无需过多交互或类似向导的工作流就可呈现内容。拥有的窗体越多,需要用户执行的选择和键入操作就越多。在这种情况下,像 RWD 这种一刀切的做法就不太合适了。那么,我们处于什么情况?

行业需要一种有效的方法以向任何设备提供适当的内容,而无需记住不同的 URL。RWD 是用于实现此目的的常用方法。但是,RWD 毫不客气地表明了它的设备无关性。开发人员不喜欢进行设备检测。要使一个网站在多个浏览器中看起来一样需要分析用户代理字符串并引入无数的代码分支,这种经历可不是一种愉快的记忆。

通过功能检测进行设备检测

在等待所有浏览器最终都可通过标准的对象模型公开平台和功能的同时,分析用户代理字符串是目前找出真正从网站请求页面的浏览器的唯一方法。分析用户代理是一种挑战,但只有少数几个工具可在一定程度上缓解痛苦。

这些工具之一就是您从 detectmobilebrowsers.com 获得的脚本。此脚本使用正则表达式检查已知移动关键字的列表,并回答以下问题:“它是移动的吗?”在此上下文中,移动只是意味着它不是桌面浏览器。另一个工具是 Modernizr,它具有一个很长的插件列表,可供用户代理分析和检测触摸事件以尝试检测平板电脑。

但是,Modernizr 并不是适合检测所有设备的工具,可检测的 JavaScript 功能除外。并且,浏览器是平板电脑还是智能手机不是您可以使用 JavaScript 检测出的。您只能通过 JavaScript 向浏览器询问它的身份,但大多数浏览器(尤其是移动浏览器)由于各种原因导致返回的信息不正确,包括由基于用户代理的旧代码进行的错误识别。

Modernizr 率先开始探究设备检测与功能检测。这是苹果和桔子的比较。它们是不同的事物,为不同的目的提供服务。如果您需要确定请求设备的外形规格,功能检测并不适用。一些开发人员通过要求 Modernizr 检查触摸事件以凭借 JavaScript 来检测平板电脑和智能手机。考虑到支持触摸的桌面和您希望作为桌面对待的设备越来越多,这种做法也愈加不可靠。

您需要专家帮助分析用户代理并返回能够轻松使用的信息。专家帮助意味着某些框架在投放市场时会不断地进行更新以添加新设备。这也暗示着复杂分析逻辑,即正确处理误报并使用统计分析以解决一些移动浏览器传递的不正确信息。坦白地讲,这会带来巨大的工作量。但是,仍有一些公司可以为您执行此任务。这些工具称为设备描述存储库 (DDR)。

WURFL.JS 终结点

一种轻型的 JavaScript 设备检测,可以改进客户端密集型 Web 应用程序(如单页应用程序 (SPA))的 UX。WURFL (wurfl.sourceforge.net) 作为服务器端解决方案几年来一直是颇受欢迎的 DDR。在我的 2013 年 8 月专栏“在 ASP.NET MVC 4 中创建为移动设备优化的视图,第 2 部分:使用 WURFL”(msdn.microsoft.com/magazine/dn342866) 中提到了在 ASP.NET MVC 应用程序中使用 WURFL。

无论您是在本地使用还是访问云中的 DDR,服务器端 WURFL 都需要支付许可证费用。WURFL 团队最近发布了免费的 HTTP 终结点 (WURFL.JS),您可以通过 JavaScript 从客户端进行调用。若要通过 WURFL.JS 终结点启用 JavaScript 设备检测,您需要做的就是将以下行添加到 HTML(在 ASP.NET 中,您甚至可以将其放置在主页面或布局文件):

<script type="text/javascript" src="http://wurfl.io/wurfl.js"></script>

引用的资源 — wurfl.js — 明显不是可以下载并本地托管或上载至您的云站点中的普通 JavaScript 文件。它是类似 JavaScript 的 HTTP 终结点,其将 JavaScript 对象恰好注入文档对象模型 (DOM) 中。实际效果是一旦浏览器调用该端点,您的 DOM 就会包含以下内容:

var WURFL = {
  "complete_device_name":"iPhone 5",
  "is_mobile":false,
  "form_factor":"Smartphone"};

浏览器进行请求时发出其用户代理字符串。以服务器端 WURFL 框架为后盾,该终结点将分析该字符串并确定有关请求设备的关键信息。然后,此类信息将格式化至名为 WURFL 的全局对象中的三个属性(参见图 1)。有趣的是,请注意,WURFL.JS 还可检测到您的网页是否是从本机移动应用的 WebView 组件内进行查看的。当 form_factor 属性返回应用时,就会出现此情况。

图 1 WURFL.JS 注入 DOM 页中的设备信息

属性 说明
complete_device_name 包含检测到设备的描述性名称,通常包括供应商和设备名称(例如,iPhone 5)。
form_factor 包含几个预定义字符串之一,如:桌面、应用、平板电脑、智能手机、功能手机、智能电视、机器人、其他非移动设备、其他移动设备。
is_mobile 布尔值,该值指示设备是否不是桌面。

WURFL.JS 使用大量的缓存以确保快速响应。在开发阶段,您可以通过将 debug=true 添加至 URL 关闭缓存。触发 DOM 就绪事件时,您可以安全地使用 WURFL 对象启用或禁用客户端功能或请求到服务器的可选数据。

WURFL.JS 助力 RWD

假设您有一个带视频的页面,由于性能原因,您不希望在智能手机上播放。使用普通 RWD,您无法轻易作出调整。如果将视频播放器隐藏在给定断点之下,则在桌面浏览器调整至小窗口时,您将不能够播放任何内容。WURFL.JS 与 RWD 一起使用就可解决此问题,如下所示:

<script type="text/javascript">
  $(document).ready(function () {
    if (WURFL.form_factor == "Smartphone") {
      $("#video_player").hide();
    }
  });
</script>

首先,加载页面并根据 RWD 布局对其设置样式。接下来,使用 WURFL 检查外形规格并隐藏视频播放器。桌面浏览器调整至智能手机大小时,用户将仍将能够播放视频,但在真正的智能手机上却不能播放。可以对之前的代码进行更好的表述,如下所示:

<script type="text/javascript">
  $(document).ready(function () {
    if (WURFL.form_factor != "Desktop" &&
        WURFL.form_factor != "Tablet") {
      $("#video_player").hide();
    }
  });
</script>

在此例中,视频播放器在所有情况下都处于隐藏状态,除非设备是桌面或平板电脑。这里还有一个更有趣的 WURFL.JS 情形。假设您在生产环境中有一个 RWD 站点,其中所有视图都在服务器上生成(例如,在 ASP.NET MVC 应用程序内)。

在某些时候,您将获得智能手机用户体验不佳的反馈。您应考虑为这些用户创建一个全新的 m 站点吗?如果您可以使用 WURFL 的服务器端服务,那么您就可以在同一站点内轻松实现视图切换器,正如我在 2013 年 8 月的专栏中所述。

此方法会保存您已完成的大部分工作。否则,除了创建一个单独站点并实现某些重定向机制以外您没有什么可以做的,如我在 2015 年 1 月的专栏“移动化现有网站”中所述 (msdn.microsoft.com/magazine/dn890366)。若要在同一 URL 下显示常规站点和 m 站点,仍需要在服务器端上完成一些良好的设备检测。

使用 WURFL.JS 的一个优点是可以从 WURFL 对象收集设备信息,并将其传递到 Google Analytics。这可以让您立即了解用户访问站点的方式以及他们最常用的设备。如果升级到新的 analytics.js,您需要以下内容:

<script type="text/javascript">
  /* Universal tracking code of Google Analytics:
    see http://goo.gl/HakYmP
  */
  ga('create', 'UA-XXXX-Y', 'auto');
  ga('send', 'pageview', {'dimension1': WURFL.form_factor});
</script>

如果您使用的是经典的 Google Analytics 脚本 (ga.js),您需要进行少量改动:

_gaq.push(['_setCustomVar', 1, 'form_factor', WURFL.form_factor, 1]);

Google Analytics 有大量的内置功能用于跟踪移动和平板电脑流量。同样,移动流量包含平板电脑流量,例如并不能立即分开智能手机与平板电脑。WURFL.JS 首先会在 Google Analytics 中添加缺少的便利信息,以便您可以创建只关注这些数字而不是数据投影的自定义报表。不过,WURFL.JS 只是一个数据提供程序。其可与 Google Analytics 配合使用,也可与其他分析工具一起使用。

总结

在许多情况下,RWD 站点要比普通 ASP.NET Web 窗体网站更难实现、费用更贵。不要被 RWD 的夸大宣传所迷惑。RWD 是桌面和高端设备的理想解决方案,但要在小型设备上有效实现对于业务至关重要的功能时,其可能不适用。RWD 很重视设备无关性。这意味着 RWD 网站向 480 x 360 经调整的桌面浏览器窗口和全屏幕小型功能手机提供的是相同的内容。

而这两种情况下的硬件和连接可能显著不同。客观地讲,性能是 RWD 的弱点。在同一时间,对所有站点采用同一种方法可能不会令人头痛。性能问题会影响主要的低级设备。如果这些设备不是常见的站点访问者,那么您可以继续高兴地使用 RWD。

但是,在不久的将来,要处理的数据量和用户期望可能都会有所提升。这就会导致更多设备不胜任,理想情况下,需要临时视图。在本文中,我介绍了一种用于检测基础设备的轻型且近乎完美的客户端解决方案 — WURFL.JS。

WURFL.JS 是一个将设备信息(特别是外形规格)注入 DOM 中的终结点。换言之,它可以告诉您该设备是桌面、平板电脑、智能手机、旧式手机、Xbox 还是可能是一个本机应用。您可以根据这些信息安排页面中的小更改,甚至将外形规格信息发送至分析工具。

通过基于每个外形规格了解站点的执行方式,您可以轻松确定成功与否以及需要改进的地方。若想详细了解如何结合使用 WURFL.JS 与 Google Analytics,请参阅 bit.ly/1u0lpGB


Dino Esposito 是《Microsoft .NET:Architecting Applications for the Enterprise》(Microsoft Press,2014 年)和《Programming ASP.NET MVC 5》(Microsoft Press,2014 年)的合著者。作为 JetBrains 的 Microsoft .NET Framework 和 Android 平台的技术推广人员,Esposito 经常在全球行业活动中发表演讲,并在 software2cents.wordpress.com 上以及 twitter.com/despos 上的推文中分享他对于软件的愿景。

衷心感谢以下技术专家对本文的审阅:Jon Arne Saeteras