是否可以使用JavaScript检测用户是否通过浏览器或应用程序进行访问?
我正在通过网页和PhoneGap应用程序为多个移动操作系统开发混合应用程序,目标是:
答案 0 :(得分:58)
您可以检查当前网址是否包含http
协议。
var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
// PhoneGap application
} else {
// Web page
}
答案 1 :(得分:15)
想到快速解决方案,
onDeviceReady
会帮助你。由于此JS调用仅由Native桥(objC或Java)调用,因此safari移动浏览器将无法检测到此情况。因此,您的设备应用(手机间隙)源基础将从onDeviceReady
开始。
如果任何Phonegap的JS调用如Device.platform或Device.name为NaN或null,那么它显然是一个移动网络电话。
请检查并告知我们结果。
答案 2 :(得分:11)
我找到了一种方法来实现这一点而不依赖于deviceready事件,从而保持Web代码库的完整性......
使用内置的deviceready事件的当前问题是,当页面加载时,您无法告诉应用程序:“嘿,这不是在移动设备上运行,没有必要等待设备准备开始“。
1.-在代码的原生部分,例如iOS,在MainViewController.m中有一个方法viewDidLoad,我发送一个javascript变量,我稍后在Web代码中检查,如果该变量在,我将等待为我的页面启动代码,直到所有内容都准备好(例如,导航器地理位置)
在MainViewController.m下:
- (void) viewDidLoad
{
[super viewDidLoad];
NSString* jsString = [NSString stringWithFormat:@"isAppNative = true;"];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
2.- index.html代码如下:
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){;
myApp.run();
}
try{
if(isAppNative!=undefined);
}catch(err){
$(document).ready(function(){
myApp.run();
});
}
答案 3 :(得分:7)
PhoneGap有window.PhoneGap(或在Cordova,它的window.cordova或window.Cordova)对象集。检查该对象是否存在并进行魔术。
答案 4 :(得分:6)
在加载了phonegap应用的网址的本机通话中,添加一个带有值phonegap的参数目标。因此对android的调用变成了这样的东西。
super.loadUrl("file:///android_asset/www/index.html?target=phonegap");
使用此代码的网站不会使用额外参数调用,因此我们现在在两个部署平台之间有不同的内容
在javascript中我们检查参数是否存在,如果是,我们为phonegap / cordova添加脚本标记。
var urlVars = window.location.href.split('?'); if(urlVars.length > 1 && urlVars[1].search('target=phonegap') != -1){ //phonegap was used for the call $('head').append('<script src="cordova.js"></script>'); }一个小警告:此方法需要在每个不同的目标移动平台的phonegap中更改对index.html的调用。我不熟悉大多数平台在哪里这样做。
答案 5 :(得分:4)
我对phonegap应用和我们的网络客户端使用相同的代码。以下是我用来检测phonegap是否可用的代码:
window.phonegap = false;
$.getScript("cordova-1.7.0.js", function(){
window.phonegap = true;
});
请记住,phonegap js文件是异步加载的。您可以通过设置漂亮的jquery $ .getScript函数的正确选项来同步加载它。
请注意,即使在您的webclient中,该方法也会获取额外的GET请求以获取phonegap js文件。就我而言,它并没有影响我的webclient的性能;所以它最终是一个很好/干净的方式来做到这一点。至少在其他人找到一个快速的单行解决方案之前:)
答案 6 :(得分:4)
听起来,一旦webview在Phonegap应用中启动,你正在加载另一个网页,这是正确的吗?如果这是真的,那么您可以根据配置向请求URL添加一个参数。
例如,假设PHP,
App.Config = {
target: "phonegap"
};
<body onload="onbodyload()">
var onbodyload = function () {
var target = App.Config.target;
document.location = "/home?target=" + target;
};
然后在服务器端,如果目标是phonegap,请包含phonegap js。
无法使用用户代理检测差异。
答案 7 :(得分:4)
我正在使用的方法是使用一个全局变量,该变量被仅限浏览器版本的cordova.js覆盖。在您的主html文件(通常是index.html
)中,我有以下与顺序相关的脚本:
<script>
var __cordovaRunningOnBrowser__ = false
</script>
<script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
<script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->
在cordova.js
里面我只是:
__cordovaRunningOnBrowser__ = true
在为移动设备构建时,不会使用cordova.js(而是使用特定于平台的cordova.js文件),因此无论协议如何,此方法都具有100%正确的优势,userAgents或库变量(可能会改变)。我应该在cordova.js中包含其他内容,但我不知道它们到底是什么。
答案 8 :(得分:4)
我一直在努力解决这个问题,我知道这是一个老线程,但我还没有看到我的方法,所以想想id分享它会帮助某人。
我在实际使用者之后设置了一个自定义的useragent:
String useragent = settings.getUserAgentString();
settings.setUserAgentString(useragent + ";phonegap");
只是添加了phonegap字符串,以便依赖于检测您的移动用户的其他网站仍然有效。
然后你可以像这样加载phonegap:
if( /phonegap/i.test(navigator.userAgent) )
{
//you are on a phonegap app, $getScript etc
} else {
alert("not phonegap");
}
答案 9 :(得分:4)
如果您尝试以下内容该怎么做:
if(window._cordovaNative) {
alert("loading cordova");
requirejs(["...path/to/cordova.js"], function () {
alert("Finished loading cordova");
});
}
答案 10 :(得分:1)
在我看来,你试图为自己制造问题。您没有提到您的开发平台,但大多数都有不同的部署配置。您可以定义两个配置。并设置变量,指示代码的部署方式。 在这种情况下,您无需关心部署应用程序的设备。
答案 11 :(得分:1)
简短有效:
if (document.location.protocol == 'file:') { //Phonegap is present }
答案 12 :(得分:1)
与B T's solution类似,但更简单:
我的 www 文件夹中有一个空的cordova.js,在构建时会被Cordova覆盖。别忘了在应用程序脚本文件之前加入cordova.js(花了我一个小时的时间才知道我的错误顺序......)。
然后,您可以检查Cordova对象:
document.addEventListener('DOMContentLoaded', function(){
if (window.Cordova) {
document.addEventListener('DeviceReady', bootstrap);
} else {
bootstrap();
}
});
function bootstrap() {
do_something()
}
答案 13 :(得分:0)
新解决方案:
var isPhoneGapWebView = location.href.match(/^file:/); // returns true for PhoneGap app
旧解决方案:
使用jQuery,像这样运行
$(document).ready(function(){
alert(window.innerHeight);
});
以iPhone为例,为您的移动应用程序
使用PhoneGap或Cordova时,你会得到460px的WebView,但在safari中,由于浏览器的默认页眉和页脚,你会失去一些高度。
如果window.innerHeight等于460,你可以加载phonegap.js,并调用 onDeviceReady
函数
答案 14 :(得分:0)
目前还没有人提到这一点,但似乎Cordova现在支持将浏览器添加为平台:
cordova platforms add browser
这将在运行时自动添加cordova.js,其中包含onDeviceReady
事件,因此您无需伪造它。此外,许多插件都支持浏览器,因此代码中不再存在浏览器攻击。
要在浏览器中使用您的应用,您应该使用cordova run browser
。如果要部署它,可以使用与其他平台相同的命令来执行此操作。
编辑:忘了提及my source。
答案 15 :(得分:0)
解决方案:在Cordova中修补index.html并将cordova-platform="android"
添加到<html>
标记中,以便cordova-platform属性仅在Cordova构建中存在,而在用于外部Web的原始index.html中丢失科尔多瓦。
优点:不依赖于用户代理,URL架构或cordova API。不需要等待deviceready事件。可以通过各种方式进行扩展,例如,是否包含cordova-platform =“ browser”,以区分Cordova之外的Web应用程序和Cordova的浏览器平台。
与config.xml合并
<platform name="android">
<hook src="scripts/patch-android-index.js" type="after_prepare" />
</platform>
添加文件脚本/patch-android-index.js
module.exports = function(ctx) {
var fs = ctx.requireCordovaModule('fs');
var path = ctx.requireCordovaModule('path');
var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
var indexPath = platformRoot + '/app/src/main/assets/www/index.html';
var indexSource = fs.readFileSync(indexPath, 'utf-8');
indexSource = indexSource.replace('<html', '<html cordova-platform="android"');
fs.writeFileSync(indexPath, indexSource, 'utf-8');
}
注意:对于非android系统,应调整路径platforms/android
和/app/src/main/assets/www/index.html
。
应用程序可以使用以下命令检查cordova平台
if (! document.documentElement.getAttribute('cordova-platform')) {
// Not in Cordova
}
或
if (document.documentElement.getAttribute('cordova-platform') === 'android') {
// Cordova, Android
}