8

I have an html-javascript page, and I need to detect whenever it open on web view (Like inside facebook webview, twitter webview, etc.), and if it a webview - display another content.

Note: I do not control the third-party Android apps, so I cannot make changes to their code.

I already found a way to detect an IOS webview (Found it on stackoverflow):

var isIosWebview =/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent)

Now I'm looking for a javascript code that can detect Android web view.

Help?

Sender
  • 6,660
  • 12
  • 47
  • 66
Megi Ben Nun
  • 405
  • 3
  • 6
  • 20

4 Answers4

8

You can't detect it by only using the user agent string, as any app that uses WebView can set the UA string to anything it wants.

If you still insist on using the UA string, this is the explanation of the official docs: initially, Chromium-based WebView was using .0.0.0 as Chrome version suffix; in the newer versions ; wv was added into the platform part of the UA string. Note that pre-KitKat WebViews didn't have the Chrome part. See older posts about that: Android, webview user agent vs browser user agent

Another hint of WebView involvement is presence of X-Requested-With HTTP header with an application package name. Note that this header is also set by XMLHttpRequest, so you need to look for the actual value of the header.

The statement that WebView doesn't support iframes is not correct.

Community
  • 1
  • 1
Mikhail Naganov
  • 6,643
  • 1
  • 26
  • 26
  • How do I get the "X-Requested-With" . I looked it up, and didn't found a good way to get it. – Megi Ben Nun Aug 09 '15 at 13:39
  • You can see it on the server. There is no way to see it from the page side. – Mikhail Naganov Aug 09 '15 at 15:31
  • 1
    in flask python, you can do `request.headers.get('X-Requested-With')` and it will give you the package name incase of webView. It helped me to block the apps which are illegally showing my website on webViews. – scottydelta Feb 13 '17 at 09:51
5

The info others provided in this thread gave me what I needed to solve this problem in my case. For others, here is the resulting JS regex which represents the detection described in the accepted answer:

/(Version\/\d+.*\/\d+.0.0.0 Mobile|; ?wv|(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari))/i.test(navigator.userAgent)

The regex includes cases for old Android, new Android, iOS versions.

Max Harper
  • 51
  • 1
  • 1
  • I just copy pasted this answer into our web view detection hook in our PWA. But it doesn't seem to detect old android phones, tested on my nexus 5x, android 8.1.0. Seems like everything prior to when they included the handy "wv" in the user agent string doesn't get detected. Any input on this appreciated. – Operator Mar 23 '22 at 23:03
0

I know how to do it. It is very simple. Because there is an object used by Android web view to trigger functions in its Android app via javascript. So in your js code you can use:

if (typeof Android === "undefined") {
    // do something if is NOT a web view
} else {
    // do something else if is a web view
}
silvanasono
  • 394
  • 1
  • 4
  • 11
  • 1
    Thanks! From my recent experience, I realize that, whenever you use such an interface object in your javascript, you will want to perform this type of test to make sure you can at least test the look of your pages in a browser. – Papa Smurf Jul 15 '19 at 21:53
  • This does not seem to work for me. I have tried in an Android Webview inside of an emulator. – gil.fernandes Nov 02 '19 at 16:45
  • @gil.fernandes this code is JavaScript, it is not used in Android code – silvanasono Dec 02 '19 at 14:12
  • Tried this. JavaScript. Did not work for me in Facebook Android webview. (typeof Android === "undefined") apparently returned True – Joshua Wolff Dec 20 '19 at 09:32
-1

I needed to detect if the browser was an Android WebView without using the User-Agent (since it can be spoofed), and without reading the Headers server-side.

It appears they were quite sneaky in hiding this, but you can check if the window has a property named "Android " (with a space at the end). This appears to be true only when being used as a WebView inside an app, and not in Chrome on the same device.

const isAndroidWebView = window.hasOwnProperty('Android ')

Disclaimer: I have only verified this on a Pixel 3 running Android 10, and a Nokia 6 running Android 9. Please comment if this does or doesn't work for your device.

Sean Adkinson
  • 8,425
  • 3
  • 45
  • 64