简体   繁体   English

检测用户是否使用 webview for android/iOS 或常规浏览器

[英]Detect if user is using webview for android/iOS or a regular browser

How to detect if the user is browsing the page using webview for android or iOS ?如何检测用户浏览的页面是使用webviewandroid还是iOS

There are various solutions posted all over stackoverflow, but we don't have a bulletproof solution yet for both OS. stackoverflow 上发布了各种解决方案,但我们还没有针对这两种操作系统的防弹解决方案。

The aim is an if statement, example:目的是一个 if 语句,例如:

if (android_webview) {
    jQuery().text('Welcome webview android user');
} else if (ios_webview) {
    jQuery().text('Welcome webview iOS user');
} else if (ios_without_webview) {
    // iOS user who's running safari, chrome, firefox etc
    jQuery().text('install our iOS app!');
} else if (android_without_webview) {
    // android user who's running safari, chrome, firefox etc
    jQuery().text('install our android app!');
}

What I've tried so far到目前为止我试过的

Detect iOS webview ( source ):检测 iOS webview来源):

if (navigator.platform.substr(0,2) === 'iP'){

  // iOS (iPhone, iPod, iPad)
  ios_without_webview = true;

  if (window.indexedDB) {
    // WKWebView
    ios_without_webview = false; 
    ios_webview = true; 
  }

}

Detect android webview , we have a number of solutions like this and this .检测android webview ,我们有很多这样这样的解决方案。 I'm not sure what's the appropriate way to go because every solution seems to have a problem.我不确定 go 的正确方法是什么,因为每个解决方案似乎都有问题。

Detecting browser for iOS devices is different from the Android one.检测 iOS 设备的浏览器与 Android 设备不同。 For iOS devices you can do it by checking user agent using JavaScript:对于 iOS 设备,您可以通过使用JavaScript 检查用户代理来做到这一点:

var userAgent = window.navigator.userAgent.toLowerCase(),
    safari = /safari/.test( userAgent ),
    ios = /iphone|ipod|ipad/.test( userAgent );

if( ios ) {
    if ( safari ) {
        //browser
    } else if ( !safari ) {
        //webview
    };
} else {
    //not iOS
};

For Android devices, you need to do it through server side coding to check for a request header.对于 Android 设备,您需要通过服务器端编码来检查请求标头。

PHP: PHP:

if ($_SERVER['HTTP_X_REQUESTED_WITH'] == "your.app.id") {
    //webview
} else {
    //browser
}

JSP: JSP:

if ("your.app.id".equals(req.getHeader("X-Requested-With")) ){
    //webview
} else {
    //browser
}

Ref: detect ipad/iphone webview via javascript参考: 通过 javascript 检测 ipad/iphone webview

Note: This solution is PHP-based.注意:此解决方案是基于 PHP 的。 HTTP headers can be faked so this is not the nicest solution but you can have a start with this. HTTP标头可以伪造,因此这不是最好的解决方案,但您可以从这里开始。

//For iOS

if ((strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile/') !== false) && (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari/') == false) {
    echo 'WebView';
} else{
    echo 'Not WebView';
}

//For Android

if ($_SERVER['HTTP_X_REQUESTED_WITH'] == "com.company.app") {
    echo 'WebView';
} else{
    echo 'Not WebView';
}

For me this code worked:对我来说,这段代码有效:

var standalone = window.navigator.standalone,
  userAgent = window.navigator.userAgent.toLowerCase(),
  safari = /safari/.test(userAgent),
  ios = /iphone|ipod|ipad/.test(userAgent);

if (ios) {
  if (!standalone && safari) {
    // Safari
  } else if (!standalone && !safari) {
    // iOS webview
  };
} else {
  if (userAgent.includes('wv')) {
    // Android webview
  } else {
    // Chrome
  }
};

This is the extended version of rhavendc's answer .这是rhavendc 答案的扩展版本。 It can be used for showing app install banner when a website is visited from browser, and hiding the banner when a website is opened in a webview.它可用于在从浏览器访问网站时显示应用安装横幅,并在 Web 视图中打开网站时隐藏横幅。

$iPhoneBrowser  = stripos($_SERVER['HTTP_USER_AGENT'], "iPhone");
$iPadBrowser    = stripos($_SERVER['HTTP_USER_AGENT'], "iPad");
$AndroidBrowser = stripos($_SERVER['HTTP_USER_AGENT'], "Android");
$AndroidApp = $_SERVER['HTTP_X_REQUESTED_WITH'] == "com.company.app";
$iOSApp = (strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile/') !== false) && (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari/') == false);

if ($AndroidApp) {
    echo "This is Android application, DONT SHOW BANNER";
}
else if ($AndroidBrowser) {
    echo "This is Android browser, show Android app banner";
}
else if ($iOSApp) {
    echo "This is iOS application, DONT SHOW BANNER";
}
else if($iPhoneBrowser || $iPadBrowser) {
    echo "This is iOS browser, show iOS app banner";
}

Complementing the above answers, to find out if it's webview on newer versions of android, you can use the expression below:作为上述答案的补充,要确定它是否是较新版本的 android 上的 webview,您可以使用以下表达式:

const isWebView = navigator.userAgent.includes ('wv')

See details of this code at https://developer.chrome.com/multidevice/user-agent#webview_user_agent .https://developer.chrome.com/multidevice/user-agent#webview_user_agent查看此代码的详细信息。

For anyone out there who is having issues in year 2022 with apple deciding to drop 'ipad' in the useragent, I had to tweak the script a little to make it work:对于那些在 2022 年遇到苹果决定在用户代理中删除“ipad”的问题的人,我不得不稍微调整脚本以使其工作:

function isWebview() { if (typeof window === undefined) { return false }; function isWebview() { if (typeof window === undefined) { return false };

    let navigator = window.navigator;

    const standalone = navigator.standalone;
    const userAgent = navigator.userAgent.toLowerCase();
    const safari = /safari/.test(userAgent);
    const ios = /iphone|ipod|ipad/macintosh.test(userAgent);
    const ios_ipad_webview = ios && !safari;

    return ios ? ( (!standalone && !safari) || ios_ipad_webview ) : userAgent.includes('wv');
}

I found this simple-to-use package is-ua-webview我发现这个简单易用的包是-ua-webview

intall: $ npm install is-ua-webview安装: $ npm install is-ua-webview

Javascript: Javascript:

var isWebview = require('is-ua-webview');    
var some_variable = isWebview(navigator.userAgent);

Angular2+:角2+:

import * as isWebview from 'is-ua-webview';
const some_variable = isWebview(navigator.userAgent);

If you're using Flask (and not PHP), you can check to see if "wv" is in the string for the "User-Agent" header.如果您使用的是 Flask(而不是 PHP),您可以检查“wv”是否在“User-Agent”标头的字符串中。 Feel free to edit / add a more precise way of checking it, but basically "wv" is put there if it's a web view;随意编辑/添加更精确的检查方式,但如果是网页视图,基本上“wv”会放在那里; otherwise, it is not there.否则,它不存在。

user_agent_header = request.headers.get('User-Agent', None)
is_web_view = "wv" in str(header_request) if user_agent_header is not None else False

Chrome Developer Docs: Chrome 开发者文档:

WebView UA in Lollipop and Above Lollipop 及更高版本中的 WebView UA

In the newer versions of WebView, you can differentiate the WebView by looking for the wv field as highlighted below.在较新版本的 WebView 中,您可以通过查找 wv 字段来区分 WebView,如下所示。

Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36 Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36

A simple solution that is found for this issue is passing a parameter in url when hitting webview and check if the parameter exists and is it from android or IOS.针对此问题找到的一个简单解决方案是在点击 webview 时在 url 中传递一个参数,并检查该参数是否存在以及它来自 android 还是 IOS。 It works only when you have access to App source code.它仅在您有权访问 App 源代码时才有效。 otherwise you can check for user agent of request.否则您可以检查请求的用户代理。

I came to decision, that instead of detection, more efficient solution simply specify platform in AppConfig.我决定,而不是检测,更有效的解决方案只是在 AppConfig 中指定平台。

const appConfig = {
   appID: 'com.example.AppName.Web'
   //or
   //appID: 'com.example.AppName.MobileIOS'
   //or
   //appID: 'com.example.AppName.MobileAndroid'
}

The following works for me as well: (in case you get puzzled and undefined index for $_SERVER['HTTP_X_REQUESTED_WITH'] )以下内容也适用于我:(如果您对$_SERVER['HTTP_X_REQUESTED_WITH']索引感到困惑和未定义)

if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == "com.systechdigital.bgmea") { 
    // web view Android
} else if ( (strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile/') !== false) && (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari/') == false) ) {
    // web view iOS
}
else {
    // responsive mobile view or others (e.g. desktop)
}

WebView UA in Lollipop and Above Lollipop 及更高版本中的 WebView UA

In the newer versions of WebView, you can differentiate the WebView by looking for the wv field as highlighted below.在较新版本的 WebView 中,您可以通过查找 wv 字段来区分 WebView,如下所示。

在此处输入图像描述

More Details - https://developer.chrome.com/docs/multidevice/user-agent/更多详细信息 - https://developer.chrome.com/docs/multidevice/user-agent/

Updated the solution using TypeScript: https://codepen.io/davidrl1000/pen/YzeaMem使用 TypeScript 更新了解决方案: https ://codepen.io/davidrl1000/pen/YzeaMem

 const isWebview = () => { if (typeof window === undefined) { return false }; let navigator: any = window.navigator; const standalone = navigator.standalone; const userAgent = navigator.userAgent.toLowerCase(); const safari = /safari/.test(userAgent); const ios = /iphone|ipod|ipad/.test(userAgent); return ios ? !standalone && !safari : userAgent.includes('wv'); }

For iOS I've found that you can reliably identify if you're in a webview (WKWebView or UIWebView) with the following:对于 iOS,我发现您可以通过以下方式可靠地识别您是否在 web 视图(WKWebView 或 UIWebView)中:

var isiOSWebview = (navigator.doNotTrack === undefined && navigator.msDoNotTrack === undefined && window.doNotTrack === undefined);

Why it works: All modern browsers (including webviews on Android) seem to have some sort of implementation of doNotTrack except webviews on iOS.为什么有效:所有现代浏览器(包括 Android 上的 webviews)似乎都有某种 doNotTrack 实现,除了 iOS 上的webviews In all browsers that support doNotTrack, if the user has not provided a value, the value returns as null, rather than undefined - so by checking for undefined on all the various implementations, you ensure you're in a webview on iOS.在所有支持 doNotTrack 的浏览器中,如果用户没有提供值,则该值返回为 null,而不是 undefined - 因此,通过在所有各种实现上检查 undefined,您可以确保您在 iOS 上的 web 视图中。

Note: This will identify Chrome, Firefox, & Opera on iOS as being a webview - that is not a mistake.注意:这会将 iOS 上的 Chrome、Firefox 和 Opera 识别为 web 视图 - 这不是错误。 As noted in various places online , Apple restricts 3rd party browser developers on iOS to UIWebView or WKWebView for rendering content - so all browsers on iOS are just wrapping standard webviews except Safari.正如网上各个地方所指出的那样,Apple 将 iOS 上的第 3 方浏览器开发人员限制为 UIWebView 或 WKWebView 来呈现内容 - 因此 iOS 上的所有浏览器都只是包装了标准的 webviews,除了 Safari。

If you need to know you're in a webview, but not in a 3rd party browser, you can identify the 3rd party browsers by their respective user agents :如果您需要知道您在 web 视图中,而不是在第 3 方浏览器中,您可以通过各自用户代理识别第 3 方浏览器:

(isiOSWebview && !(/CriOS/).test(navigator.userAgent) && !(/FxiOS/).test(navigator.userAgent) && !(/OPiOS/).test(navigator.userAgent)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM