detect ipad/iphone webview via javascript

JavascriptIpadIosWebview

Javascript Problem Overview


Is there a way to detect with JavaScript if the website runs inside the iPad's Safari or inside an application WebView?

Javascript Solutions


Solution 1 - Javascript

This uses a combination of window.navigator.userAgent and window.navigator.standalone. It can distinguish between all four states relating to an iOS web app: safari (browser), standalone (fullscreen), uiwebview, and not iOS.

Demo: http://jsfiddle.net/ThinkingStiff/6qrbn/

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 ) {
        //browser
    } else if ( standalone && !safari ) {
        //standalone
    } else if ( !standalone && !safari ) {
        //uiwebview
    };
} else {
    //not iOS
};

Solution 2 - Javascript

User Agents

Running in UIWebView

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176

Running in Safari on iPad

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3

Running in Safari on Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3

Running in Chrome on Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19

Running in FireFox on Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0

Detection Code

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

Solution 3 - Javascript

I think that you can just use the User-Agent.


UPDATE

Page browsed using iPhone Safari

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7

I will try in a second with UIWebView

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/8B117

The difference is that the Safari one says Safari/6531.22.7


Solution

var isSafari = navigator.userAgent.match(/Safari/i) != null;

Solution 4 - Javascript

I've tried all these solutions but didn't work in my case,
I was going to detect the Webview inside Telegram. I think it uses SFSafariViewController.
I noticed Safari app changes all phone style texts to links with "tel:" prefix but a webview doesn't.
So, I used that.
test it here : jsfiddle

<!DOCTYPE html>
<html>
<head></head>
<body>
<ul id="phone" style="opacity:0">
    <li>111-111-1111</li>
</ul>
</body>
</html>

<script>

    var html = document.getElementById("phone").innerHTML;

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

        if (html.indexOf('tel:') == -1)
            alert('not safari browser');
        else
            alert('safari browser');
    }
    else
        alert('not iOS');
</script>

Solution 5 - Javascript

Yeah:

// is this an IPad ?
var isiPad = (navigator.userAgent.match(/iPad/i) != null);

// is this an iPhone ?
var isiPhone = (navigator.userAgent.match(/iPhone/i) != null);

// is this an iPod ?
var isiPod = (navigator.userAgent.match(/iPod/i) != null);

Solution 6 - Javascript

> Note that this approach does not work for iOS 10 and older versions.

For the Spring of 2018 none of proposed method worked for me so I came up with a new approach (which is not userAgent based):

const hasValidDocumentElementRatio =
  [ 320 / 454 // 5, SE
  , 375 / 553 // 6, 7, 8
  , 414 / 622 // 6, 7, 8 Plus
  , 375 / 812 // X
  , 414 / 896 // Xs, Xr
  ].some(ratio =>
    ratio === document.documentElement.clientWidth / 
      document.documentElement.clientHeight
  )

const hasSafariInUA = /Safari/.test(navigator.userAgent)

const isiOSSafari = hasSafariInUA && hasValidDocumentElementRatio  // <- this one is set to false for webviews

https://gist.github.com/BorisChumichev/7c0ea033daf33da73306a396ffa174d1

You are welcome to extend the code for iPad devices too, I think it should do the trick.

Worked well for Telegram, Facebook, VK webviews.

Solution 7 - Javascript

Neoneye's solution does not work anymore (see comments) and can be simplified. On the other hand, testing only "Safari" in the UA adresses much more than the ios handheld devices.

This is the test i'm using :

var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);

Solution 8 - Javascript

Try With IOS 13

      function mobileDetect() {


    var agent = window.navigator.userAgent;
    var d = document;
    var e = d.documentElement;
    var g = d.getElementsByTagName('body')[0];
    var deviceWidth = window.innerWidth || e.clientWidth || g.clientWidth;

    // Chrome
    IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;

    // iPhone
    IsIPhone = agent.match(/iPhone/i) != null;

    // iPad up to IOS12
    IsIPad = (agent.match(/iPad/i) != null) || ((agent.match(/iPhone/i) != null) && (deviceWidth > 750)); // iPadPro when run with no launch screen can have error in userAgent reporting as an iPhone rather than an iPad. iPadPro width portrait 768, iPhone6 plus 414x736 but would probably always report 414 on app startup

    if (IsIPad) IsIPhone = false;

    // iPad from IOS13
    var macApp = agent.match(/Macintosh/i) != null;
    if (macApp) {
        // need to distinguish between Macbook and iPad
        var canvas = document.createElement("canvas");
        if (canvas != null) {
            var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
            if (context) {
                var info = context.getExtension("WEBGL_debug_renderer_info");
                if (info) {
                    var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
                    if (renderer.indexOf("Apple") != -1) IsIPad = true;
                }
                ;
            }
            ;
        }
        ;
    }
    ;

    // IOS
    IsIOSApp = IsIPad || IsIPhone;

    // Android
    IsAndroid = agent.match(/Android/i) != null;
    IsAndroidPhone = IsAndroid && deviceWidth <= 960;
    IsAndroidTablet = IsAndroid && !IsAndroidPhone;



    message = ""


    if (IsIPhone) {

        message = "Device is IsIPhone"


    }
    else if (IsIPad) {

        message = "Device is ipad"

    } else if (IsAndroidTablet || IsAndroidPhone || IsAndroid) {

        message = "Device is Android"


    } else {

        message = "Device is Mac ||  Windows Desktop"

    }


    return {

        message: message,

        isTrue: IsIOSApp || IsAndroid || IsAndroidTablet || IsAndroidPhone

    }

}



const checkMobile = mobileDetect()

alert(checkMobile.message + "  =====>  " + checkMobile.isTrue)

Solution 9 - Javascript

I know this code will check if it is being accessed from an icon added to the home screen:

if (window.navigator.standalone == true) {
//not in safari
}

but I'm not sure how it would react in a UIWebView. The only other solution I could think of is getting the user agent or using - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType and replacing the query string of the page you are accessing with something the page uses to identify that it is being accessed from a web view.

Solution 10 - Javascript

Would suggest using Modernizr, and checking for indexeddb like this. You could cross-check that with user agent configuration (device, OS, browser, etc), but pure feature detection seems more recommended.

Solution 11 - Javascript

Last time I needed this (JUST for WebView purposes), I used this check:

function isIOS() {
     return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}

Solution 12 - Javascript

I have found a simple solution to detect iPhone or iPad. This works for me fine.

var is_iPad = navigator.userAgent.match(/iPad/i) != null;
var is_iPhone = navigator.userAgent.match(/iPhone/i) != null;
    if(is_iPad || is_iPhone == true){
        //perform your action
    }

Solution 13 - Javascript

Working 15.02.19

Another solution for detecting webviews on iOS is checking for the support / existence of navigator.mediaDevices.

if (navigator.mediaDevices) {
    alert('has mediaDevices');
} else {
    alert('has no mediaDevices');
}

In my case I didn't need to catch all webviews, but those that don't support camera / microphone input (Reminder: Alerts don't trigger in Webview, so make sure to change something in the dom for debug purposes)

Solution 14 - Javascript

It is 2022 and Safari version is 15.4. None of the above solutions worked for me. There are two webview classes on iOS: WKWebView and SFSafariViewController. SFSafariViewController has the same userAgent as Safari. The solution I came up with relies on how height: 100vh is handled on Mobile Safari. 100vh is the device screen height, not the document visible height.

For more info see:

https://developers.google.com/web/updates/2016/12/url-bar-resizing

https://bugs.webkit.org/show_bug.cgi?id=141832

https://github.com/bokand/URLBarSizing

So, on iOS a function like this detects a WebView mode.

function isWebView()
{
    const htmlEl = document.getElementsByTagName('html')[0];
    const bodyEl = document.getElementsByTagName('body')[0];

    const oldHtmlHeight = htmlEl.style.height;
    const oldBodyHeight = bodyEl.style.height;

    htmlEl.style.height = "100vh";
    bodyEl.style.height = "100%";

    const webViewMode = document.documentElement.clientHeight === document.documentElement.scrollHeight;

    // restore height
    htmlEl.style.height = oldHtmlHeight;
    bodyEl.style.height = oldBodyHeight;

    return webViewMode;
}

Solution 15 - Javascript

I don't think there's anything specific you can use in client-side Javascript, but if you have control over what the originating UIWebView can do, you might want to consider playing with the user agent string it generates, and testing for that in your client-side Javascript instead? A bit of a hack I know, but hey… This question may give some pointers on tweaking the user agent:

https://stackoverflow.com/questions/478387/change-user-agent-in-uiwebview-iphone-sdk

Solution 16 - Javascript

@ Sod, Well i don’t have answer, but i am not convinced why you want to check, Since, browser engine whether its safari ( Browser ) or Application will be same its Webkit only, Yes Application can configure the Browser engine capabilities like, whether application wants to run JS or Display Image etc…

I believe, you must check for certain property whether Flash supported by Browser or whether browser displays image or not, or probably may be you would like to check the screen size,

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsodView Question on Stackoverflow
Solution 1 - JavascriptThinkingStiffView Answer on Stackoverflow
Solution 2 - JavascriptneoneyeView Answer on Stackoverflow
Solution 3 - JavascriptNicolas SView Answer on Stackoverflow
Solution 4 - JavascriptAmir KhorsandiView Answer on Stackoverflow
Solution 5 - JavascriptJohn DohertyView Answer on Stackoverflow
Solution 6 - JavascriptBoris ChumichevView Answer on Stackoverflow
Solution 7 - JavascripteosphereView Answer on Stackoverflow
Solution 8 - JavascriptMahmoud D. AlghraibehView Answer on Stackoverflow
Solution 9 - JavascriptPrestonView Answer on Stackoverflow
Solution 10 - JavascriptjikuView Answer on Stackoverflow
Solution 11 - JavascriptCatalinBertaView Answer on Stackoverflow
Solution 12 - JavascriptVijay DhanvaiView Answer on Stackoverflow
Solution 13 - JavascriptvinniView Answer on Stackoverflow
Solution 14 - JavascriptMilen YordanovView Answer on Stackoverflow
Solution 15 - JavascriptBenView Answer on Stackoverflow
Solution 16 - JavascriptAmitg2k12View Answer on Stackoverflow