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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8068052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:36:09  来源:igfitidea点击:

PhoneGap: Detect if running on desktop browser

javascriptcordova

提问by aaronsnoswell

I'm developing a web application that uses PhoneGap:Build for a mobile version and want to have a single codebase for the 'desktop' and mobile versions. I want to be able to detect if PhoneGap calls will work (ie, is the user on a mobile device that will support PhoneGap).

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

I've searched and cannot believe there is no simple way of doing this. Many people have offered suggestions;

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

None of which work, unless you remove the PhoneGap Javascript file from the desktop version of the app, which defeats my goal of having one codebase.

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

So far the only solution I have come up with is browser / user agent sniffing, but this is not robust to say the least. Any better solutions welcome!

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

EDIT: A marginally better solution is to try calling a PhoneGap function after some small timeout - if it doesn't work, then assume the user is on a desktop web browser.

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

采纳答案by sirmdawg

I use this code:

我使用这个代码:

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

UPDATE

更新

There are many other ways to detect if phonegap is running on a browser or not, here is another great option:

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

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

as seen here: Detect between a mobile browser or a PhoneGap application

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

回答by Slavik Meltser

I wrote a postabout it a few days ago. This is the best solution you can find (until PhoneGap will release something, maybe or maybe not), it's short, simple and perfect (I've checked it in every possible way and platform).

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

This function will do the job for 98% of the cases.

此功能将在 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!");
}

To complete the other 2% of the cases, follow these steps (it involves a slight change on native code):

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

Create a file called __phonegap_index.html, with the source:

创建一个名为__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>

Now, on native simply change the start page from index.htmlto __phonegap_index.htmlon all your PhoneGap platforms. Let's say my project name is example, the files you need to change are (as for PhoneGap version 2.2.0):

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

  • iOS- CordovaLibApp/AppDelegate.m
  • Android- src/org/apache/cordova/example/cordovaExample.java
  • Windows 8- example/package.appxmanifest
  • BlackBerry- www/config.xml
  • WebOS- framework/appinfo.json
  • Bada- src/WebForm.cpp(line 56)
  • Window Phone 7- No idea where (somebody still developing on that platform?!)
  • 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- 不知道在哪里(有人还在那个平台上开发?!)

Finally, you can use it anywhere on your site, if it's running on PhoneGap or not:

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

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

Hope it helps. :-)

希望能帮助到你。:-)

回答by fredericrous

I know it's been answered a while ago but "PhoneGap.available" doesn't exist anymore. You should use:

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

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

or since 1.7, prefer:

或从 1.7 开始,更喜欢:

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

EDIT 2019: as said in the comments, this only works if you do not include cordova lib into your desktop browser build. And of course it is a good practice to include only the strict minimum javascript/html/css files for each device you target

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

回答by jrobichaud

The most trustable way we found to tell if we are in a cordova/phonegap application is to modify the cordova application's user agent using this config AppendUserAgent.

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

In config.xmladd:

另外config.xml

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

Then call:

然后调用:

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

Why?

为什么?

  1. window.cordovaand document.addEventListener('deviceready', function(){});are subject to racing conditions
  2. navigator.standalonedoes not work when <content src="index.html" />is a website (Ex: <content src="https://www.example.com/index.html" />or with cordova-plugin-remote-injection)
  3. Trying to whitelist user agents to guess if it is a real browser is very complicated. Android browsers are often custom webviews.
  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。

回答by Yuval

I think this is simplest: var isPhoneGap = (location.protocol == "file:")

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

EDITFor some people that didn't work. Then you might try (haven't tested)

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

var isPhoneGap = ! /^http/.test(location.protocol);

回答by Rob

This works for me (running 1.7.0)

这对我有用(运行 1.7.0)

if (window.device) {
  // Running on PhoneGap
}

Tested on desktop Chrome and Safari.

在桌面 Chrome 和 Safari 上测试。

回答by Jim H.

Like the original poster, I'm using the phonegap build service. After two days and nearly 50 test builds, I've come up with an elegant solution that works great for me.

像原始海报一样,我正在使用 phonegap 构建服务。经过两天和近 50 次测试构建,我想出了一个非常适合我的优雅解决方案。

I couldn't use UA sniffing because I wanted to test and run in mobile browsers. I had originally settled on cobberboy's quite functional technique. This didn't work for me because the "howPatientAreWe: 10000" delay/timeout was too much of a nuisance for in-browser development. And setting it any lower would occasionally fail the test in app/device mode. There had to be another way...

我不能使用 UA 嗅探,因为我想在移动浏览器中测试和运行。我最初选择了 cobberboy 非常实用的技术。这对我不起作用,因为“howPatientAreWe:10000”延迟/超时对于浏览器内的开发来说太麻烦了。将它设置得更低有时会在应用程序/设备模式下测试失败。必须有另一种方式......

The phonegap build service requires the phonegap.jsfile be omitted from your code repository before submitting your app's files to the service. Therefore I'm able to test for its existence to determine if running in a browser vs. app.

phonegap.js在将应用程序的文件提交给服务之前,phonegap 构建服务要求从代码存储库中省略该文件。因此,我可以测试它的存在,以确定是在浏览器还是应用程序中运行。

One other caveat, I'm also using jQueryMobile, so both jQM and phonegap had to initialize before I could begin any custom scripting. The following code is placed at the beginning of my custom index.js file for the app (after jQuery, before jQM). Also the phonegap build docs say to place <script src="phonegap.js"></script>somewhere in the HTML. I leave it out completely and load it using $.getScript() to facility testing its existence.

另一个警告,我也在使用 jQueryMobile,所以 jQM 和 phonegap 都必须初始化,然后才能开始任何自定义脚本。以下代码位于应用程序的自定义 index.js 文件的开头(在 jQuery 之后,在 jQM 之前)。此外,phonegap 构建文档还说要放置<script src="phonegap.js"></script>在 HTML 中的某个位置。我完全忽略它并使用 $.getScript() 加载它来测试它的存在。

isPhoneGap = false;
isPhoneGapReady = false;
isjQMReady = false;

$.getScript("phonegap.js")
.done(function () {
    isPhoneGap = true;
    document.addEventListener("deviceready", function () {
        console.log("phonegap ready - device/app mode");
        isPhoneGapReady = true;
        Application.checkReadyState();
    }, false);
})
.fail(function () {
    console.log("phonegap load failed - browser only");
    isPhoneGapReady = true;
    Application.checkReadyState();
});

$(document).bind("mobileinit", function () {
    Application.mobileInit();
    $(document).one("pageinit", "#Your_First_jQM_Page", function () {
        isjQMReady = true;
        Application.checkReadyState();
    });
});

Application = {
    checkReadyState: function () {
        if (isjQMReady && isPhoneGapReady) {
            Application.ready();
        }
    },
    mobileInit: function () {
        // jQM initialization settings go here
        // i.e. $.mobile.defaultPageTransition = 'slide';
    },
    ready: function () {
        // Both phonegap (if available) and jQM are fired up and ready
        // let the custom scripting begin!
    }
}

回答by Frodik

Interestingly, many answers, but they don't include these three options:

有趣的是,答案很多,但不包括这三个选项:

1 – The cordova.js will set the cordova object in the global scope. If it is there then you are most likely running in a Cordova scope.

1 – cordova.js 将在全局范围内设置 cordova 对象。如果它在那里,那么您很可能在 Cordova 范围内运行。

var isCordovaApp = !!window.cordova;

2 – Cordova will run your application as you would open a HTML document from your Desktop. Instead of the HTTP protocol it will use FILE. Detecting this will give you a chance to assume that your app was loaded locally.

2 – Cordova 将运行您的应用程序,就像您从桌面打开 HTML 文档一样。它将使用 FILE 代替 HTTP 协议。检测到这一点将使您有机会假设您的应用程序是在本地加载的。

var isCordovaApp = document.URL.indexOf('http://') === -1
  && document.URL.indexOf('https://') === -1;

3 – Use the load event of the cordova script to detect the context. The script include can be easily removed in the build process or the script loading will simply fail in a browser. So that this global variable will not be set.

3 – 使用cordova 脚本的load 事件来检测上下文。脚本包含可以在构建过程中轻松删除,否则脚本加载将在浏览器中失败。这样就不会设置这个全局变量。

<script src="../cordova.js" onload="javascript:window.isCordovaApp = true;"></script>

Credit goes to Damien Antipa from Adobe

幸得达Antipa从Adobe

回答by andreszs

I use this method:

我用这个方法:

debug = (window.cordova === undefined);

debugwill be trueon the browser environment, falseon the device.

debugtrue在浏览器环境中,false在设备上。

回答by Deminetix

This seems to be viable and I have used it in production:

这似乎是可行的,我已经在生产中使用了它:

if (document.location.protocol == "file:") {
    // file protocol indicates phonegap
    document.addEventListener("deviceready", function() { $(initInternal);} , false);
}
else {
    // no phonegap, start initialisation immediately
    $(initInternal);
}

Source: http://tqcblog.com/2012/05/09/detecting-phonegap-cordova-on-startup/

来源:http: //tqcblog.com/2012/05/09/detecting-phonegap-cordova-on-startup/