简体   繁体   English

无法在旧 android 版本上使用 Javascript 和用户代理检测 webview

[英]Not possible to detect webview with Javascript and user agent on old android versions

I'm struggling on solving a really annoying issue for android.我正在努力解决一个非常烦人的 android 问题。 We are running our PWA inside of a webview - that's how websites can be ported to android apps.我们在 webview 中运行我们的 PWA - 这就是网站可以移植到 Android 应用程序的方式。 I'm trying to solve the issue with detecting if it's running inside of a webview on android - if it is it shouldn't display "use app" button and cookie bar etc. The old android versions just refuses to detect this - hence still showing the button.我正在尝试通过检测它是否在 android 上的 webview 内运行来解决这个问题 - 如果是,它不应该显示“使用应用程序”按钮和 cookie 栏等。旧的 android 版本只是拒绝检测到这一点 - 因此仍然显示按钮。 Only the new ones detect it, android 11 etc.只有新的检测到它,android 11 等。

Have used the following NPM package that is supposed to detect it but still to no success.使用了以下 NPM 包,它应该可以检测到它,但仍然没有成功。

https://www.npmjs.com/package/is-ua-webview https://www.npmjs.com/package/is-ua-webview

I faced the same problem.我遇到了同样的问题。 This package is-ua-webview is quite old (the last update was about 2 years ago) and I suggest it doesn't work in the right way.这个包is-ua-webview已经很老了(最后一次更新大约是 2 年前) ,我建议它不能以正确的方式工作。

The current problem is here: https://github.com/atomantic/is-ua-webview/blob/master/data/rules.js#L8当前的问题在这里: https ://github.com/atomantic/is-ua-webview/blob/master/data/rules.js#L8

I don't know why, but the author tries to detect WebView by 0.0.0 version.不知道为什么,作者尝试通过0.0.0版本来检测 WebView。

'Android.*(wv|.0.0.0)',

But as you can see in many sources there are combinations with devices and browsers that have Android.*.0.0.0 string in the User-Agent, but it's still not WebView, it's a mobile browser.但是正如您在许多来源中看到的那样,在 User-Agent 中存在与具有Android.*.0.0.0字符串的设备和浏览器的组合,但它仍然不是 WebView,它是一个移动浏览器。

For example, this is the User-Agent string in Mobile Chrome browser on Samsung Galaxy S21 (Android 12) Mozilla/5.0 (Linux; Android 12; SM-G996B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36 .例如,这是三星 Galaxy S21 (Android 12) Mozilla/5.0 (Linux; Android 12; SM-G996B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36上的 Mobile Chrome 浏览器中的 User-Agent 字符串Mozilla/5.0 (Linux; Android 12; SM-G996B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Mobile Safari/537.36 It contains Android.*102.0.0.0 and this package defines this browser as a WebView.它包含Android.*102.0.0.0 ,并且此包将此浏览器定义为 WebView。

Actually, I can't find how the .0.0.0 ending binds with the WebView (maybe just this: https://developer.chrome.com/docs/multidevice/webview/#what-version-of-chrome-is-it-based-on , but it's an article of 2014 year) , but I found this helpful article about detecting WebView: Developer Chrome - webview user agent实际上,我找不到.0.0.0结尾如何与 WebView 绑定(也许只是这样: https ://developer.chrome.com/docs/multidevice/webview/#what-version-of-chrome-is- 它基于,但它是 2014 年的文章) ,但我发现这篇关于检测 WebView 的有用文章: Developer Chrome - webview user agent

We need to check Version/_X.X_ (Version/4.0 for example) in our User-Agent string.我们需要在我们的用户代理字符串中检查Version/_X.X_ (例如版本/4.0) Even in this article was said:甚至在这篇文章中说:

Don't rely on the specific Chrome version number (for example, 30.0.0.0) as the version numbers changes with each release不要依赖特定的 Chrome 版本号(例如,30.0.0.0),因为版本号会随每个版本而变化

Actually whole code of is-ua-webview package looks like this:实际上is-ua-webview包的整个代码如下所示:


const rules = [
  // if it says it's a webview, let's go with that
  'WebView',
  // iOS webview will be the same as safari but missing "Safari"
  '(iPhone|iPod|iPad)(?!.*Safari)',
  // Android Lollipop and Above: webview will be the same as native but it will contain "wv"
  // Android KitKat to lollipop webview will put {version}.0.0.0
  'Android.*(wv|.0.0.0)',
  // old chrome android webview agent
  'Linux; U; Android'
]

var webviewRegExp = new RegExp('(' + rules.join('|') + ')', 'ig')

module.exports = function isWebview(ua) {
  return !!ua.match(webviewRegExp)
}

We can just replace the 'Android.*(wv|.0.0.0)', string to new 'Version/[0-9]\.[0-9]' according to this article Developer Chrome - webview user agent我们可以根据这篇文章Developer Chrome - webview user agent'Android.*(wv|.0.0.0)',字符串替换为新'Version/[0-9]\.[0-9]'

Final solution:最终解决方案:

const rules = [
  // if it says it's a webview, let's go with that
  'WebView',
  // iOS webview will be the same as safari but missing "Safari"
  '(iPhone|iPod|iPad)(?!.*Safari)',
  // https://developer.chrome.com/docs/multidevice/user-agent/#webview_user_agent
  'Android.*Version/[0-9]\.[0-9]',
  // Also, we should save the wv detected for Lollipop
  // Android Lollipop and Above: webview will be the same as native but it will contain "wv"
  'Android.*wv',
  // old chrome android webview agent
  'Linux; U; Android'
]

var webviewRegExp = new RegExp('(' + rules.join('|') + ')', 'ig')

module.exports = function isWebview(ua) {
  return !!ua.match(webviewRegExp)
}

By the way, as I understood sometimes the user can see the whole functionality of the Chrome browser in WebView: https://developer.android.com/about/versions/nougat/android-7.0#webview顺便说一句,据我了解,有时用户可以在 WebView 中看到 Chrome 浏览器的全部功能: https ://developer.android.com/about/versions/nougat/android-7.0#webview

I hope it helps you.我希望它对你有帮助。 Thanks谢谢

you can explicitly set the agent string of the webview in your app to a unique string, and detect that agent string on your web app side.您可以将应用程序中 webview 的代理字符串显式设置为唯一字符串,并在您的 web 应用程序端检测该代理字符串。 webview.getSettings().setUserAgentString("my-webview-agent-string"); webview.getSettings().setUserAgentString("my-webview-agent-string");

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

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