PhoneGap:检测是否在桌面浏览器上运行

IT技术 javascript cordova
2021-03-18 16:14:11

我正在开发一个使用 PhoneGap:Build 移动版本的 Web 应用程序,并希望为“桌面”和移动版本拥有一个单一的代码库。我希望能够检测 PhoneGap 呼叫是否有效(即,用户是否使用支持 PhoneGap 的移动设备)。

我已经搜索过并且无法相信没有简单的方法可以做到这一点。很多人提出了建议;

除非您从应用程序的桌面版本中删除 PhoneGap Javascript 文件,否则这些都不起作用,这违背了我拥有一个代码库的目标。

到目前为止,我想出的唯一解决方案是浏览器/用户代理嗅探,但这至少可以说不可靠。欢迎任何更好的解决方案!

编辑:稍微好一点的解决方案是在一些小的超时后尝试调用 PhoneGap 函数 - 如果它不起作用,则假设用户在桌面 Web 浏览器上。

6个回答

我使用这个代码:

if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/)) {
  document.addEventListener("deviceready", onDeviceReady, false);
} else {
  onDeviceReady(); //this is the browser
}

更新

还有许多其他方法可以检测 phonegap 是否在浏览器上运行,这是另一个不错的选择:

var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
    // PhoneGap application
} else {
    // Web page
}  

如此处所示:在移动浏览器或 PhoneGap 应用程序之间检测

我很困惑,Windows Phone 等其他平台呢?他们是否有与该正则表达式匹配的 userAgent?快速谷歌搜索意味着不是:madskristensen.net/post/Windows-Phone-7-user-agents.aspx
2021-04-20 16:14:11
当您在设备浏览器中打开应用程序时,这无济于事。更好的解决方案:检查 window.cordova。在 iPhone 模拟器(浏览器)或 Android 设备(浏览器)中进行测试也应该检测到 PhoneGap。这就是我发展的方式。但是有很多可能性来完成事情。;-) 感谢发布您的解决方案!
2021-04-27 16:14:11
不确定您在说什么 - 但您似乎暗示这会导致使用手机浏览器时出现问题...这是在您的桌面浏览器而非手机上进行测试的解决方案。
2021-05-02 16:14:11
谢谢你 - 在等了很长时间看看其他人的建议之后,这似乎是最好的解决方案。干杯。
2021-05-10 16:14:11
这是不准确的,因为如果我在设备的浏览器上打开同一个页面, onDeviceReady() 将永远不会调用。另外,如果我要更改浏览器中的 UserAgent(出于调试目的),onDeviceReady() 也不会调用。
2021-05-14 16:14:11

几天前我写了一篇关于它帖子这是你能找到的最好的解决方案(直到 PhoneGap 发布一些东西,也许会或也许不会),它简短、简单和完美(我已经在所有可能的方式和平台上进行了检查)。

此功能将在 98% 的情况下完成工作。

/**
 * Determine whether the file loaded from PhoneGap or not
 */
function isPhoneGap() {
    return (window.cordova || window.PhoneGap || window.phonegap) 
    && /^file:\/{3}[^\/]/i.test(window.location.href) 
    && /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isPhoneGap() ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

要完成另外 2% 的案例,请按照以下步骤操作(它涉及对本机代码的轻微更改):

创建一个名为__phonegap_index.html的文件,其来源为:

<!-- __phonegap_index.html -->
<script type="text/javascript">
    function isPhoneGap() {
        //the function's content is as described above
    }

    //ensure the 98% that this file is called from PhoneGap.
    //in case somebody accessed this file directly from the browser.
    if ( isPhoneGap() )
        localStorage.setItem("isPhoneGap","1");

    //and redirect to the main site file.
    window.location = "index.html";
</script>

现在,在本机上,只需将所有 PhoneGap 平台上的起始页从index.html更改__phonegap_index.html假设我的项目名称是example,您需要更改的文件是(对于 PhoneGap 版本 2.2.0):

  • iOS -CordovaLibApp/AppDelegate.m
  • 安卓——src/org/apache/cordova/example/cordovaExample.java
  • 视窗 8 -example/package.appxmanifest
  • 黑莓-www/config.xml
  • 网络操作系统-framework/appinfo.json
  • 八达- src/WebForm.cpp(第 56 行)
  • Window Phone 7 - 不知道在哪里(有人还在那个平台上开发?!)

最后,您可以在站点的任何位置使用它,无论它是否在 PhoneGap 上运行:

if ( localStorage.getItem("isPhoneGap") ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

希望能帮助到你。:-)

@rojobuffalo:看起来答案已被修改,使其再次按预期工作(ReferenceError,由于window前缀,它不再抛出 a )。只是想我会指出这一点,因为这实际上使评论链过时(因此,不正确)。
2021-04-30 16:14:11
发现这个答案是最好的!
2021-05-07 16:14:11
是的,它可以工作,但有时代码的下一部分不正确,/^file:\/{3}[^\/]/i.test(window.location.href)但我们正在使用 PhoneGap,例如从另一个页面加载 index.html 时,在 config.xml 上是这样的<content src="http://10.100.1.147/" />
2021-05-08 16:14:11
@rblakeley 你是对的。我将第一行切换为:return ( typeof cordova !== undefined || typeof PhoneGap !== undefined || typeof phonegap !== undefined )
2021-05-10 16:14:11
(cordova || PhoneGap || phonegap) 如果这些变量中的任何一个未定义,则表达式将引发 ReferenceError。你应该用 测试typeof cordova !== undefined,对吧?
2021-05-11 16:14:11

我知道它已经被回答了一段时间,但“PhoneGap.available”不再存在。你应该使用:

if (window.PhoneGap) {
  //do stuff
}

或从 1.7 开始,更喜欢:

if (window.cordova) {
  //do stuff
}

编辑 2019:如评论中所述,这仅在您未将cordova lib 包含到桌面浏览器构建中时才有效。当然,为您定位的每个设备只包含严格的最小 javascript/html/css 文件是一个好习惯

如果使用 PhoneGap Build,这似乎会特别有效。
2021-04-21 16:14:11
这不是真的,因为 window.PhoneGap 或 window.cordova 如果您包含脚本cordova-xxxjs,即使它已加载到浏览器上,也将始终被定义。
2021-04-22 16:14:11
现在这似乎是正确的答案(至少对于 Cordova 3.4)。所有其他方法都只是浪费时间,因为现在使用简单的 <script type="text/javascript" src="cordova.js"></script> 将cordova.js 注入到应用程序中。您实际上并未指向真实文件,因此在浏览器中运行时不会加载它。它只存在于在移动设备上运行的 Cordova 版本中。
2021-05-04 16:14:11
@SlavikMe 不要在非cordova 构建中包含cordova 脚本。
2021-05-11 16:14:11
你能帮我举个例子吗。简单地加载index.html。我正在做的是我已经上传了本地服务器www文件夹下的所有文件,我正在加载index.html。但是设备准备好了没有被解雇。
2021-05-17 16:14:11

我们发现判断我们是否在 cordova/phonegap 应用程序中的最可靠方法是使用此配置AppendUserAgent修改cordova 应用程序的用户代理

另外config.xml

<preference name="AppendUserAgent" value="Cordova" />

然后调用:

var isCordova = navigator.userAgent.match(/Cordova/i))

为什么?

  1. window.cordovadocument.addEventListener('deviceready', function(){});受赛车条件的限制
  2. navigator.standalone<content src="index.html" />是网站时不起作用(例如:<content src="https://www.example.com/index.html" />或使用cordova-plugin-remote-injection
  3. 尝试将用户代理列入白名单以猜测它是否是真正的浏览器非常复杂。Android 浏览器通常是自定义的 webview。
这似乎是最万无一失的方法。亚军似乎正在测试文档 URL 中是否缺少 http:// 或 https://,但我可以想象可能的情况,这可能不起作用。
2021-04-22 16:14:11
我们甚至可以在那里添加应用程序版本!(理想情况下带有一些自动版本的碰撞逻辑)例如;Cordova AppName/v0.0.1<3 这样,您甚至可以以某种方式使用它进行跟踪(但请注意,任何人都可以修改其用户代理,因此不要依赖它进行安全关键验证)
2021-05-07 16:14:11
毕竟这是对我有用的。谢谢!
2021-05-11 16:14:11

我认为这是最简单的: var isPhoneGap = (location.protocol == "file:")

编辑 对于一些不起作用的人。那你可以试试(没测试过)

var isPhoneGap = ! /^http/.test(location.protocol);
当我测试远程文件时,这在涟漪模拟器中不起作用
2021-05-05 16:14:11
我以为 PhoneGap 为所有设备上的文件运行了一个内部服务器?
2021-05-10 16:14:11
在 WP8 中也不起作用,协议是“x-wmapp0:”。无法确定将来会使用哪些其他“协议”。
2021-05-11 16:14:11
我喜欢。在本地主机上开发时,这是最好的解决方案。(经过多次尝试,我希望这适用于所有场景,希望如此。)谢谢!
2021-05-14 16:14:11
好吧,你也可以 --try var isPhoneGap = ! /^http/.test(document.location.protocol)
2021-05-17 16:14:11