¿Hay alguna forma de diferenciar a través de javascript si el sitio web se ejecuta dentro del ipad safari o dentro de una aplicación WebView?
Respuestas:
Esto usa una combinación de window.navigator.userAgent
ywindow.navigator.standalone
. Puede distinguir entre los cuatro estados relacionados con una aplicación web de iOS: safari (navegador), independiente (pantalla completa), uiwebview y no iOS.
Demostración: 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
en userAgent. se comporta de manera diferente con respecto al webcal://
protocolo requerido para archivos .ics
Ejecutando en UIWebView
Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176
Ejecutar en Safari en 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
Ejecutar en Safari en 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
Ejecutando en Chrome en 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
Ejecutando en FireFox en 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
y Safari tienen Safari
en su agente de usuario
Version
en lugar de Safari
trabajar para mí en el último iOS.
Version
? ¿Reemplaza Safari
con Version
en la var is_uiwebview
línea?
Creo que puedes usar el User-Agent
.
ACTUALIZAR
Página navegada con Safari de iPhone
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
Lo intentaré en un segundo con 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
La diferencia es que el de Safari dice Safari/6531.22.7
Solución
var isSafari = navigator.userAgent.match(/Safari/i) != null;
Safari/.....
a que falta el mismo en UIWebView
Si:
// 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);
Probé todas estas soluciones pero no funcionó en mi caso,
iba a detectar Telegram dentro de Webview. Me di cuenta de que Safari está cambiando el texto del estilo del teléfono a un enlace con el prefijo "tel:", así que usé esto para escribir este código, puedes probarlo: 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'
. Esto afecta especialmente a iPadOS 13 Mobile Safari porque usa el modo de escritorio de forma predeterminada.
La solución de Neoneye ya no funciona (ver comentarios) y se puede simplificar. Por otro lado, probar solo "Safari" en la UA aborda mucho más que los dispositivos de mano ios.
Esta es la prueba que estoy usando:
var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);
Tenga en cuenta que este enfoque no funciona para iOS 10 y versiones anteriores.
Para la primavera de 2018, ninguno de los métodos propuestos funcionó para mí, así que se me ocurrió un nuevo enfoque (que no está basado en 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
También puede ampliar el código para dispositivos iPad, creo que debería funcionar.
Funcionó bien para Telegram, Facebook, VK webviews.
Working 15.02.19
Otra solución para detectar vistas web en iOS es verificar el soporte / existencia de navigator.mediaDevices
.
if (navigator.mediaDevices) {
alert('has mediaDevices');
} else {
alert('has no mediaDevices');
}
En mi caso, no necesitaba capturar todas las vistas web, pero las que no admiten la entrada de cámara / micrófono (Recordatorio: las alertas no se activan en la vista web, así que asegúrese de cambiar algo en el dom para fines de depuración)
Sé que este código comprobará si se accede a él desde un icono añadido a la pantalla de inicio:
if (window.navigator.standalone == true) {
//not in safari
}
pero no estoy seguro de cómo reaccionaría en un UIWebView. La única otra solución que se me ocurre es obtener el agente de usuario o usar - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
y reemplazar la cadena de consulta de la página a la que está accediendo por algo que la página usa para identificar que se está accediendo desde una vista web.
La última vez que necesité esto (SOLO para propósitos de WebView), utilicé esta verificación:
function isIOS() {
return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}
Encontré una solución simple para detectar iPhone o iPad. Esto funciona bien para mí.
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
}
Prueba con 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)
No creo que haya nada específico que pueda usar en Javascript del lado del cliente, pero si tiene control sobre lo que puede hacer el UIWebView de origen, es posible que desee considerar jugar con la cadena de agente de usuario que genera y probarlo en su ¿Javascript del lado del cliente en su lugar? Es un truco, lo sé, pero bueno ... Esta pregunta puede dar algunos consejos sobre cómo modificar el agente de usuario:
@ Sod, bueno, no tengo la respuesta, pero no estoy convencido de por qué desea verificar, ya que el motor del navegador si su safari (navegador) o la aplicación será el mismo, solo su Webkit, sí, la aplicación puede configurar las capacidades del motor del navegador como , ya sea que la aplicación quiera ejecutar JS o Display Image, etc.
Creo que debe verificar cierta propiedad si Flash es compatible con el navegador o si el navegador muestra una imagen o no, o probablemente le gustaría verificar el tamaño de la pantalla,