Existe uma maneira de diferenciar via javascript se o site for executado dentro do ipad safari ou dentro de um aplicativo WebView?
Respostas:
Isso usa uma combinação de window.navigator.userAgent
e window.navigator.standalone
. Ele pode distinguir entre todos os quatro estados relacionados a um aplicativo da web iOS: safari (navegador), autônomo (tela inteira), uiwebview e não 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
};
Safari
no userAgent. ele se comporta de maneira diferente em relação à webcal://
Executando em UIWebView
Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176
Executando no Safari no 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
Executando no Safari no 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
Executando no Chrome no 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
Executando no FireFox no Mac OS X
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0
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);
UIWebView
e Safari têm Safari
em seu agente de usuário
Version
em oposição a Safari
funcionou para mim no iOS mais recente.
Version
? Você substitui Safari
com Version
na var is_uiwebview
linha?
Eu acho que você pode simplesmente usar o User-Agent
.
ATUALIZAR
Página navegada usando 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
Vou tentar em um segundo com 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
A diferença é que o Safari diz Safari/6531.22.7
Solução
var isSafari = navigator.userAgent.match(/Safari/i) != null;
Safari/.....
próprio está faltando no UIWebView
Sim:
// 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);
Eu tentei todas essas soluções, mas não funcionou no meu caso,
eu ia detectar o Telegram dentro do Webview. Percebi que o Safari está mudando o texto do estilo do telefone para um link com o prefixo "tel:", então usei isso para escrever este código, você pode testá-lo: 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>
navigator.platform === 'MacIntel'
. Isso afeta especialmente o iPadOS 13 Mobile Safari porque ele usa o modo Desktop por padrão.
A solução do Neoneye não funciona mais (ver comentários) e pode ser simplificada. Por outro lado, testar apenas o "Safari" no UA aborda muito mais do que os dispositivos portáteis ios.
Este é o teste que estou usando:
var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);
Observe que essa abordagem não funciona para iOS 10 e versões anteriores.
Para a primavera de 2018, nenhum dos métodos propostos funcionou para mim, então eu vim com uma nova abordagem (que não é baseada em userAgent):
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
Você é bem-vindo para estender o código para dispositivos iPad também, acho que deve servir.
Funcionou bem para webviews de Telegram, Facebook e VK.
Working 15.02.19
Outra solução para detectar webviews no iOS é verificar o suporte / existência de navigator.mediaDevices
.
if (navigator.mediaDevices) {
alert('has mediaDevices');
} else {
alert('has no mediaDevices');
}
No meu caso, não precisei capturar todas as visualizações da web, mas aquelas que não suportam entrada de câmera / microfone (lembrete: os alertas não são acionados no Webview, portanto, certifique-se de alterar algo no dom para fins de depuração)
Sei que este código verificará se ele está sendo acessado por um ícone adicionado à tela inicial:
if (window.navigator.standalone == true) {
//not in safari
}
mas não tenho certeza de como isso reagiria em um UIWebView. A única outra solução que eu poderia pensar é obter o agente do usuário ou usar - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
e substituir a string de consulta da página que você está acessando por algo que a página usa para identificar que está sendo acessada de uma visualização da web.
Da última vez que precisei disso (SÓ para fins de WebView), usei esta verificação:
function isIOS() {
return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}
Eu encontrei uma solução simples para detectar iPhone ou iPad. Isso funciona bem para mim.
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
}
Experimente com 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)
Não acho que haja algo específico que você possa usar em Javascript do lado do cliente, mas se você tiver controle sobre o que o UIWebView de origem pode fazer, você pode querer brincar com a string do agente do usuário que ele gera e testar isso em seu Javascript do lado do cliente? Um pouco hack, eu sei, mas ei ... Esta pergunta pode dar algumas dicas sobre como ajustar o agente do usuário:
@ Sod, bem, eu não tenho resposta, mas não estou convencido por que você deseja verificar, uma vez que, o mecanismo do navegador se seu safari (navegador) ou aplicativo será o mesmo seu Webkit apenas, Sim O aplicativo pode configurar os recursos do mecanismo do navegador, como , se o aplicativo deseja executar JS ou Display Image etc ...
Acredito que você deve verificar certas propriedades se o Flash é compatível com o navegador ou se o navegador exibe imagem ou não, ou provavelmente você gostaria de verificar o tamanho da tela,